// ==UserScript==
// @name bili_rebuild
// @description b站评论过滤器
// @license MIT
// @namespace dreamcenter
// @version 1.0.0.5
// @match *://*.bilibili.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
/*******************************下方内容可以修改***************************************/
// 通常文本词汇屏蔽
let banMap = [
'test','随机','恶心','病','纯','ch','CH','op','策划'
];
// 小表情屏蔽,按个人需要填写
let banSmallEmoji = [
// '吃瓜','给心心','嗑瓜子'
];
// 屏蔽带有 @某人 的,默认不开启,按个人需要开启
let banAtSomeone = false
// 屏蔽笔记功能,默认不开启,按个人需要开启
let banNote = false
/*************** 下方内容通常不需要修改 *****************/
// 是否对屏蔽条目隐藏[true/false]
let hiddenMode = true
// 是否连接到云屏蔽词库[true/false]
let cloudBanMap = false
// 是否控制台打印屏蔽日志[true/false]
let logShield = false
/*******************************下方内容不要修改***************************************/
function filterStr(item){
var str=''
var childs = item.childNodes;
childs.forEach((subitem,index)=>{
if(subitem.nodeType===3){
str = subitem.nodeValue;
for(var i=0;i<banMap.length;i++){
// only chromn: str = str.replaceAll(banMap[i],'█')
str = str.replace(new RegExp(banMap[i],"gm"),'█')
}
subitem.nodeValue = str;
}
})
}
function hiddenWay(item, newVer){
var str=''
var childs = item.childNodes;
childs.forEach((subitem,index)=>{
if(subitem.nodeType===3){ // 纯文本
str = subitem.nodeValue;
for(var i=0;i<banMap.length;i++){
// only chromn: str = str.replaceAll(banMap[i],'█(' + banMap[i] + ')')
str = str.replace(new RegExp(banMap[i],"gm"),'█(' + banMap[i] + ')')
}
subitem.nodeValue = str;
if(str.indexOf('█')!=-1){
if (logShield) console.log('! :\n' + subitem.nodeValue)
handleHidden(item, newVer, false)
}
} else if (subitem.className != '' && subitem.className != undefined){ // 富文本
switch(subitem.className) {
case 'jump-link user': // @某人
if (banAtSomeone) {
handleHidden(item, newVer, false)
}
break;
case 'emoji-small': // 小表情
for(var j=0;j<banSmallEmoji.length;j++){
if (subitem.getAttribute('alt').indexOf(banSmallEmoji[j]) >= 0){
handleHidden(item, newVer, false)
}
}
break;
case 'note-prefix':
if (banNote) {
handleHidden(item, newVer, false)
}
break;
default:
// console.log(subitem.className)
break;
}
}
})
}
function handleHidden(item, newVer, testMode) {
let targetItem = item.parentNode.parentNode;
if (newVer && item.parentNode.parentNode.getAttribute("class").indexOf("root-reply") != -1) {
// new version root reply
targetItem = targetItem.parentNode.parentNode.parentNode
}
if (!newVer && item.nodeName.toLocaleLowerCase() == 'span'){
// old version root reply
targetItem = targetItem.parentNode
}
if (testMode) targetItem.style.background = 'gray'
else targetItem.style.display = 'none'
}
function cloud(){
GM_xmlhttpRequest({
method: 'GET',
url: "https://dreamcenter.github.io/test",
onload: function (res) {
let str = res.response.replace('\n','')
banMap.push(...str.split(','))
console.log(banMap)
},
onerror: function (err) {
alert("服务器连接失败")
}
})
}
(function () {
'use strict';
window.onload = function(){
// connect to the cloud ban map to get common ban map
if(cloudBanMap) cloud()
// detect and filter
let newVersion = true
setInterval(()=>{
let replies = document.querySelectorAll('p.text:not([filtered]),span.text-con:not([filtered])')
// version judge
newVersion = replies.length == 0
if (newVersion) replies = document.querySelectorAll('span.reply-content:not([filtered]),span.sub-reply-content:not([filtered])')
replies.forEach((item,index)=>{
if (hiddenMode) hiddenWay(item, newVersion)
else filterStr(item)
item.setAttribute('filtered',true)
})
},100)
}
})();