BDWM-Hide

北大未名,屏蔽版面或用户

  1. // ==UserScript==
  2. // @name BDWM-Hide
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.4
  5. // @description 北大未名,屏蔽版面或用户
  6. // @author lanvent
  7. // @match https://bbs.pku.edu.cn/v2/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=pku.edu.cn
  9. // @grant GM.setValue
  10. // @grant GM.getValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14.  
  15. let blockBlocks = [];
  16. let blockUsers = [];
  17.  
  18. async function setblockBlocks(str){
  19. blockBlocks = str.replace(',',',').split(',').map(word => word.trim()).filter(word => word.length > 0);
  20. await GM.setValue('BDWM_blockBlocks', blockBlocks);
  21. if( blockBlocks.length == 0){
  22. return;
  23. }
  24. removeBoardBlocks();
  25. removeTitles();
  26. }
  27.  
  28. async function setblockUsers(str){
  29. blockUsers = str.replace(',',',').split(',').map(word => word.trim()).filter(word => word.length > 0);
  30. await GM.setValue('BDWM_blockUsers', blockUsers);
  31. if( blockUsers.length == 0){
  32. return;
  33. }
  34. removePostCards();
  35. removePosts();
  36. }
  37.  
  38. async function setblockBlocksPrompt() {
  39. const userInput = prompt('请输入要屏蔽的版面名称,用逗号分隔:', blockBlocks.join(', '));
  40. if (userInput !== null) {
  41. await setblockBlocks(userInput);
  42. }
  43. }
  44.  
  45. async function setblockUsersPrompt() {
  46. const userInput = prompt('请输入要屏蔽的用户名称,用逗号分隔:', blockUsers.join(', '));
  47. if (userInput !== null) {
  48. await setblockUsers(userInput);
  49. }
  50. }
  51.  
  52. function addSettingsButton() {
  53. const container = document.querySelector('div.extend-menu.setting-extend-menu > div.content');
  54. if(container == null || container.querySelector('a[name="blockBlocks-button"]')){
  55. return;
  56. }
  57. const logoutButton = container.querySelector('a.btn-logout');
  58. let settingsButton = document.createElement('a');
  59. settingsButton.textContent = '屏蔽版面设置';
  60. settingsButton.name = 'blockBlocks-button';
  61. settingsButton.addEventListener('click', async function(event) {
  62. event.preventDefault();
  63. await setblockBlocksPrompt();
  64. });
  65. container.insertBefore(settingsButton,logoutButton);
  66. settingsButton = document.createElement('a');
  67. settingsButton.textContent = '屏蔽用户设置';
  68. settingsButton.name = 'blockUsers-button';
  69. settingsButton.addEventListener('click', async function(event) {
  70. event.preventDefault();
  71. await setblockUsersPrompt();
  72. });
  73. container.insertBefore(settingsButton,logoutButton);
  74. }
  75.  
  76. function addCustomSettingRow() {
  77. const form = document.getElementById('preference-form');
  78. if(form==null || form.querySelector('input[name="blockBlocks-keywords"]')){
  79. return;
  80. }
  81. const submitButtonRow = form.querySelector('.extra-margin-top');
  82. // 版面
  83. let settingRow = document.createElement('div');
  84. settingRow.className = 'form-row';
  85. settingRow.innerHTML = `
  86. <label>屏蔽版面名称</label>
  87. <div style="display: inline-block">
  88. <input type="text" name="blockBlocks-keywords" placeholder="输入版面名称,用逗号分隔" style="margin: 1px 0;
  89. padding: 0 0 0 0px;
  90. height: 28px;
  91. line-height: 28px;
  92. width: 338px;
  93. border: 1px solid #e5e5e5;
  94. border-radius: 5px;
  95. text-indent: 10px"/>
  96. </div>
  97. `;
  98. form.insertBefore(settingRow, submitButtonRow);
  99. const blocksKeywordInput = settingRow.querySelector('input[name="blockBlocks-keywords"]');
  100. blocksKeywordInput.value = blockBlocks.join(', ');
  101. // 用户
  102. settingRow = document.createElement('div');
  103. settingRow.className = 'form-row';
  104. settingRow.innerHTML = `
  105. <label>屏蔽用户名称</label>
  106. <div style="display: inline-block">
  107. <input type="text" name="blockUsers-keywords" placeholder="输入用户名,用逗号分隔" style="margin: 1px 0;
  108. padding: 0 0 0 0px;
  109. height: 28px;
  110. line-height: 28px;
  111. width: 338px;
  112. border: 1px solid #e5e5e5;
  113. border-radius: 5px;
  114. text-indent: 10px"/>
  115. </div>
  116. `;
  117. form.insertBefore(settingRow, submitButtonRow);
  118. const usersKeywordInput = settingRow.querySelector('input[name="blockUsers-keywords"]');
  119. usersKeywordInput.value = blockUsers.join(', ');
  120. const applyButton = form.querySelector('.orange-large-btn');
  121. applyButton.addEventListener('click', function(event){
  122. setblockBlocks(blocksKeywordInput.value);
  123. setblockUsers(usersKeywordInput.value);
  124. });
  125. }
  126.  
  127. function removeBoardBlocks() {
  128. //版面
  129. let boardBlocks = document.querySelectorAll('.boards-wrapper.list > div.set');
  130. if(boardBlocks!=null){
  131. boardBlocks.forEach(block => {
  132. let content = block.querySelector('span.name')?.textContent;
  133. if (content && blockBlocks.some(word => word===content)){
  134. console.log("remove block "+content,block);
  135. block.remove();
  136. }
  137. });
  138. }
  139. boardBlocks = document.querySelectorAll('.boards-wrapper.hots > div.board-block');
  140. if(boardBlocks!=null){
  141. boardBlocks.forEach(block => {
  142. let content = block.querySelector('span.name')?.textContent;
  143. if (content && blockBlocks.some(word => word===content)){
  144. console.log("remove block "+content,block);
  145. block.remove();
  146. }
  147. });
  148. }
  149. }
  150.  
  151. function removeTitles() {
  152. //主页榜单
  153. let titles = document.querySelectorAll('li');
  154. if(titles){
  155. titles.forEach(title => {
  156. let content = title.querySelector('a.post-link')?.textContent;
  157. if (content && blockBlocks.some(word => content.startsWith(word+' '))){
  158. console.log("remove block "+content.substr(0,content.lastIndexOf(' ')),title);
  159. title.remove();
  160. }
  161. content = title.querySelector('a.topic-link')?.textContent;
  162. if (content && blockBlocks.some(word => content.startsWith('['+word+']'))){
  163. console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title);
  164. title.remove();
  165. }
  166. });
  167. }
  168. //主页榜单更多
  169. titles = document.querySelectorAll('div.list-item');
  170. if(titles){
  171. titles.forEach(title => {
  172. let content = title.querySelector('div.board-cont > div.board')?.textContent;
  173. if (blockBlocks.some(word => content.startsWith(word))){
  174. console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title);
  175. title.remove();
  176. return;
  177. }
  178. let author = title.querySelector('div.author > div.name')?.textContent;
  179. if (author && blockUsers.some(word => word===author)){
  180. console.log("remove user " + author ,title);
  181. title.remove();
  182. }
  183. });
  184. }
  185. titles = document.querySelectorAll('p > a.topic-link');
  186. if(titles){
  187. titles.forEach(title => {
  188. let content = title.textContent;
  189. if (blockBlocks.some(word => title.textContent.startsWith('['+word+']'))){
  190. console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title);
  191. title.remove();
  192. }
  193. });
  194. }
  195. titles = document.querySelectorAll('a.inline-link');
  196. if(titles){
  197. titles.forEach(title => {
  198. let content = title.textContent;
  199. if (blockBlocks.some(word => title.textContent.startsWith('['+word+']'))){
  200. console.log("remove block "+content.substr(1,content.lastIndexOf(']')-1),title);
  201. title.remove();
  202. }
  203. });
  204. }
  205. }
  206.  
  207. function removePostCards() {
  208. //帖子内
  209. let postCards = document.querySelectorAll('div.card-list > .post-card');
  210. if(postCards){
  211. postCards.forEach(postcard => {
  212. let content = postcard.querySelector('p.username > a')?.textContent;
  213. if (content && blockUsers.some(word => word===content)){
  214. console.log("remove user " + content ,postcard);
  215. postcard.remove();
  216. return;
  217. }
  218. //删除引用部分
  219. let quote = postcard.querySelector('p.quotehead')
  220. content = quote?.attributes['data-username']?.textContent;
  221. if (content && blockUsers.some(word => word===content)){
  222. console.log("remove user quote " + content ,postcard);
  223. quote.remove();
  224. postcard.querySelectorAll('p.blockquote').forEach(bq => bq.remove());
  225. }
  226. });
  227. }
  228. }
  229.  
  230. function removePosts() {
  231. //版面帖子列表
  232. let posts = document.querySelectorAll('#list-content > .list-item');
  233. if(posts){
  234. posts.forEach(post => {
  235. let content = post.querySelector('.author > .name')?.textContent;
  236. if (content && blockUsers.some(word => word===content)){
  237. console.log("remove user " + content ,post);
  238. post.remove();
  239. }
  240. });
  241. }
  242. }
  243.  
  244. (async function() {
  245. 'use strict';
  246. blockBlocks = await GM.getValue('BDWM_blockBlocks', []);
  247. blockUsers = await GM.getValue('BDWM_blockUsers', []);
  248. const config = { childList: true, subtree: true };
  249. addSettingsButton();
  250. addCustomSettingRow();
  251. removeBoardBlocks();
  252. removeTitles();
  253. removePostCards();
  254. removePosts();
  255. const observer = new MutationObserver(mutations => {
  256. mutations.forEach(mutation => {
  257. if (mutation.type === 'childList') {
  258. observer.disconnect();
  259. addSettingsButton();
  260. addCustomSettingRow();
  261. observer.observe(document.body, config);
  262. removeBoardBlocks();
  263. removeTitles();
  264. removePostCards();
  265. removePosts();
  266. }
  267. });
  268. });
  269. observer.observe(document.body, config);
  270. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址