实现可分别按用户名、关键字或正则表达式对视频(或直播间/相薄)和评论(或回复)进行屏蔽; 将鼠标移至网页右下角弹出悬浮按钮
// ==UserScript==// @name 哔哩哔哩 - 屏蔽指定内容// @namespace https://greasyfork.org/zh-CN/users/193133-pana// @homepage https://greasyfork.org/zh-CN/users/193133-pana// @version 4.8.0// @description 实现可分别按用户名、关键字或正则表达式对视频(或直播间/相薄)和评论(或回复)进行屏蔽; 将鼠标移至网页右下角弹出悬浮按钮// @author pana// @include *://www.bilibili.com/*// @include *://search.bilibili.com/*// @include *://live.bilibili.com/*// @include *://space.bilibili.com/*// @include *://t.bilibili.com/*// @include *://h.bilibili.com/*// @include *://manga.bilibili.com/*// @include *://message.bilibili.com/*// @require https://cdn.jsdelivr.net/npm/[email protected]/minified/arrive.min.js// @require https://greasyfork.org/scripts/407543-block-obj/code/Block_Obj.js?version=963893// @require https://unpkg.com/[email protected]/dayjs.min.js// @license GNU General Public License v3.0 or later// @grant GM_getValue// @grant GM.getValue// @grant GM_setValue// @grant GM.setValue// @grant GM_setClipboard// @grant GM.setClipboard// @grant GM_registerMenuCommand// @grant GM_addValueChangeListener// @run-at document-start// @noframes// @note ----------------------------------------------------------------// @note 与"Bilibili 旧播放页"脚本(https://greasyfork.org/zh-CN/scripts/394296)的兼容问题:// @note 如果同时启用脚本后发现本脚本无法保存设置到存储中,请前往脚本管理器调整脚本执行顺序。// @note 具体方法可参考: https://greasyfork.org/zh-CN/scripts/397669// @note ----------------------------------------------------------------// @note 关于 "读取仅拥有标题的视频的用户名信息"// @note 原理是通过 API: "https://api.bilibili.com/x/web-interface/view"// @note 这个方法本质上是不可靠的,因为可能会由于快速大量进行请求从而导致被拦截 (如:频繁地在页面内刷新)// @note ----------------------------------------------------------------// @note 更新记录:// @note ver.4.8.0 优化关于动态的屏蔽功能// @note ver.4.7.0 支持在动态、视频播放等页面按粉丝勋章屏蔽评论// @note ver.4.6.4 补充覆盖视频播放页下部分内容// @note ver.4.6.3 修复添加正则表达式中存在逗号时录入出错的问题// @note ver.4.6.2 修复存在错误正则表达式时造成脚本失效的问题// @note ver.4.6.1 修复白名单效果未作用至动态上的问题// @note ver.4.6.0 支持用户白名单的功能// @note ver.4.5.0 支持按粉丝勋章屏蔽弹幕评论// @note ver.4.4.2 补充覆盖转发动态中的用户名// @note ver.4.4.1 修复上次更新导致屏蔽评论失效的问题// @note ver.4.4.0 优化脚本// @note ver.4.3.5 修复在视频关键字/正则表达式中添加单个空格时会导致所有视频被屏蔽的情况// @note ver.4.3.4 修复部分页面屏蔽失效的问题// @note ver.4.3.3 补充覆盖当前在线页面// @note ver.4.3.2 修复部分页面下按用户屏蔽失效的问题// @note ver.4.3.1 修复了由于上一版本的改动导致的脚本失效的问题// @note ver.4.3.0 兼容 Greasemonkey 4// @note ver.4.2.0 添加支持允许作用于动态的功能// @note ver.4.1.1 补充覆盖频道页面下内容// @note ver.4.1.0 允许在评论区显示屏蔽用户和"爆炸"按钮// @note ver.4.0.6 修复播放器网页全屏模式下的冲突问题// @note ver.4.0.4 尝试修复播放器网页全屏模式下可能的冲突问题// @note ver.4.0.3 修复已知的问题// @note ver.4.0.2 更换依赖库的 CDN// @note ver.4.0.0 整理并优化代码; 修复对于新添加的正则表达式,其无法在其他同步数据的标签页上生效的问题// @note ver.3.18.0 尝试通过 API 获取其他仅拥有标题的视频的用户名信息// @note ver.3.17.1 尝试通过 API 的方式读取专区热门列表里视频的用户名// @note ver.3.17.0 处理与"Bilibili 旧播放页"脚本不兼容的问题// @note ver.3.16.4 补充之前忘记匹配消息中心页面的问题; 补充覆盖番剧区页内的评论区; 修复了其他已知的问题// @note ver.3.16.0 增加 "消息中心 >> 回复我的" 的相关屏蔽,同时允许自动删除通知// @note ver.3.14.4 补充覆盖漫画页内的评论区// @note ver.3.14.3 增加相薄区的相关屏蔽; 完善部分未被覆盖的页面内容; 调整了使用关键字匹配表情的逻辑// @note ver.3.13.2 补充覆盖动态首页内的评论区// @note ver.3.13.1 修复可能无法匹配到用户动态页的问题// @note ver.3.13.0 实现多标签页同步数据; 调整取消按钮的行为; 覆盖视频播放完毕后的推荐视频; 兼容"Bilibili 旧播放页"脚本; 依旧存在的兼容问题: 在主页和视频播放页等页面下同时开启脚本时,本脚本无法保存设置到存储中// @note ver.3.11.0 增加直播区的相关屏蔽; 覆盖个人动态内的评论; 添加展开列表按钮// @note ver.3.7.1 添加删除按钮; 完善部分未被覆盖的页面内容// @note ver.3.5.3 修复部分页面下输入框内容看不清以及其他小问题// @note ver.3.5.0 优化代码; 完善部分未被覆盖的页面内容; 悬浮图标自动隐藏等// @note ver.2.2.0 添加允许将评论中的 b 站内置表情包转换成对应文字的功能// @note ver.2.1.2 修复储存正则表达式出错的问题; 优化代码// @note ver.2.1.0 添加允许按正则表达式进行屏蔽的功能// @note ver.2.0.0 调整了添加与删除关键字的方式,方便操作; 将评论与视频标题的关键词分开作用// @note ver.1.2.1 完善部分未被覆盖的页面内容// @note ver.1.2.0 添加屏蔽评论的功能// @note ver.1.1.2 调整屏蔽按钮的位置到右下角; 尝试处理脚本偶尔会失效的问题// @note ver.1.1.1 修复搜索页面以关键字屏蔽无效的问题// @note ver.1.1.0 匹配视频播放页面; 优化代码// ==/UserScript==(async function () {'use strict';const OLD_URL = location.href;const MODULE = {USERNAME: {className: 'li_username',},WHITELIST: {className: 'li_whitelist',},VIDEO_KEYWORD: {className: 'li_video_keyword',},COMMENT_KEYWORD: {className: 'li_comment_keyword',},};const BASIC_STYLE = `.player-mode-webfullscreen,.mode-webfullscreen,.webfullscreen,.player-module {z-index: 100001 !important;}.bilibili_reply_bang_button,.bilibili_comment_bang_button,.bilibili_reply_user_block_button,.bilibili_comment_user_block_button {display: inline-block;padding: 0px 5px;border-radius: 4px;cursor: pointer;}.bilibili_reply_bang_button:hover,.bilibili_comment_bang_button:hover,.bilibili_reply_user_block_button:hover,.bilibili_comment_user_block_button:hover {color: #00a1d6;background-color: #e5e9ef;}`;const handler = [{index: '.video-card-common',user: ['a.up', 'a.ex-up'],text: ['a.title', 'p.ex-title'],method: 1,},{clientInformation: 0,index: '.video-card-reco',user: 'p.up',text: 'p.title',},{index: '.van-slide div.item',user: null,text: 'p.title',},{index: '.rank-wrap',user: 'span.name',text: ['p.f-title', 'p.title', 'div.txt a.link p'],},{index: '.article-card',user: 'a.up',text: 'a.title',method: 1,},{index: '.live-card',user: 'p.name',text: 'p.desc',method: 1,type: {live: true,},},{index: '.card-live-module',user: '.auther',text: 'p.t',method: 1,type: {live: true,},},{index: '.live-rank-item',user: 'div.txt > p',text: 'p.p2',method: 0,type: {live: true,},},{index: '.manga-card',user: null,text: 'p.manga-title',method: 1,},{index: '.manga-spread-module',user: null,text: 'p.t',method: 1,},{c: 1,index: '.groom-module',user: 'p.author',userReg: /^up主:/,text: 'p.title',},{index: 'ul.vd-list li',user: 'a.v-author',text: 'a.title',},{index: '.video-page-card, .video-page-operator-card',user: 'div.up',text: '.title',},{index: '.rank-list li.item',user: null,text: '> a',},{c: 2,index: '.storey-box .spread-module',bv: 'a',text: 'p.t',},{index: '.ebox',user: '.author',text: '.etitle',url: ['www.bilibili.com/video/', 'www.bilibili.com/bangumi/'],comment: true,},{index: '.article-list li',user: '.nick-name',text: '.article-title',url: 'www.bilibili.com/read/ranking',},{index: '.rank-video-card, .video-card',user: '.up-name',text: '.video-name',url: ['www.bilibili.com/v/channel', 'www.bilibili.com/v/popular'],},{index: '.video-item',user: 'a.up-name',text: 'a.title',url: 'search.bilibili.com',},{index: '.live-user-item',user: '.uname',text: null,method: 0,type: {live: true,},url: 'search.bilibili.com',},{index: '.live-room-item',user: '.uname span',text: '.item-title',method: 0,type: {live: true,},url: 'search.bilibili.com',},{index: '.photo-item',user: '.up-name',text: '.title',method: 0,type: {pic: true,},url: 'search.bilibili.com',},{index: '.rank-item',user: '.room-anchor',text: '.room-title',method: 0,type: {live: true,},url: 'live.bilibili.com',comment: true,},{index: '.room-card-wrapper',user: '.room-anchor > span',text: '.room-title',method: 0,type: {live: true,},url: 'live.bilibili.com',},{index: '.ysly-room-ctnr li',user: '.uname',text: '.room-name',method: 0,type: {live: true,},url: 'live.bilibili.com',},{index: 'ul.list li',user: '.room-anchor > span',text: '.room-title',method: 0,type: {live: true,},url: 'live.bilibili.com',},{index: '.card-items li',user: '.uname',text: '.room-name',method: 0,type: {live: true,},},{index: '.content li',user: '.user-container a span',text: '.article-title a',method: 0,type: {pic: true,},url: 'h.bilibili.com',comment: true,},{index: '.rank-list > div',user: ['.name', '.user-name'],text: ['.title', '.work-name'],method: 0,type: {pic: true,},url: 'h.bilibili.com',},{index: '.canvas-card',user: '.user-container a span',text: '.article-title a',method: 1,type: {pic: true,},url: 'h.bilibili.com',},];let bilibiliConfig = {functionEnable: true,usernameEnable: true,keywordEnable: true,whitelistEnable: false,commentEnable: false,commentKeywordEnable: false,commentFans: false,convertEmojiEnable: false,showBlockUserBtnEnable: false,showBangBtnEnable: false,liveEnable: false,picEnable: false,messageReplyEnable: false,messageReplyDelEnable: false,dynamicVideo: false,dynamicContent: false,usernameArray: [],keywordArray: [],commentArray: [],whitelistArray: [],};let infoRecord = [];const tempRecord = Block_Obj.GM.getValue('infoRecord', []);tempRecord.forEach(item => {if (dayjs().diff(item.time, 'd') <= 3) {infoRecord.push(item);}});let delNum = 0;let recordButton = [];let requestTotal = 0;let sendStatus = true;const INTERVAL_TIME = 100;if (typeof Block_Obj !== 'function') {alert('Block_Obj.js was not loaded successfully.');} else if (typeof Block_Obj.fn.compare !== 'function') {alert('The version of Block_Obj.js is too low.');}let blockObj = new Block_Obj('bilibili_config', [{key: 'keywordArray',ori: 'regArray',},{key: 'commentArray',ori: 'commentRegArray',},]);await document.arrive('body', { fireOnAttributesModification: true, onceOnly: true, existing: true }, async function () {await blockObj.init({id: 'bilibiliConfig',menu: 'bilibili_屏蔽设置',style: BASIC_STYLE,field: [{id: 'functionEnable',label: '启用屏蔽功能',title: '总开关',type: 'c',default: true,},{id: 'whitelistEnable',label: '启用白名单',title: '白名单用户的视频(或直播间/相薄)以及评论(或回复)不会被屏蔽',type: 'c',default: false,move_right: true,},{label: '屏蔽视频(或直播间/相薄):',type: 's',},{id: 'usernameEnable',label: '按用户名',title: '屏蔽指定用户发布的视频(或直播间/相薄)',type: 'c',default: true,},{id: 'keywordEnable',label: '按关键字或正则',title: '屏蔽标题中包含指定关键字或匹配正则表达式的视频(或直播间/相薄)',type: 'c',default: true,move_right: true,},{id: 'liveEnable',label: '直播间',title: '扩展作用范围以同时允许屏蔽直播间',type: 'c',default: false,move_right: true,},{id: 'picEnable',label: '相薄',title: '扩展作用范围以同时允许屏蔽相薄',type: 'c',default: false,move_right: true,},{id: 'dynamicVideo',label: '动态',title: '允许屏蔽转发、分享指定用户的动态\n允许屏蔽视频标题匹配关键字或正则的动态',type: 'c',default: false,move_right: true,},{label: '屏蔽评论(或回复):',type: 's',},{id: 'commentEnable',label: '按用户名',title: '屏蔽指定用户发布的评论(或回复)',type: 'c',default: false,},{id: 'commentKeywordEnable',label: '按关键字或正则',title: '屏蔽内容中包含指定关键字或匹配正则表达式的评论(或回复)',type: 'c',default: false,move_right: true,},{id: 'commentFans',label: '按粉丝勋章',title: '屏蔽直播间中挂有指定粉丝勋章用户发布的弹幕评论\n屏蔽动态、视频播放等页面中挂有指定粉丝勋章用户发布的评论',type: 'c',default: false,move_right: true,},{id: 'dynamicContent',label: '动态',title: '允许屏蔽动态内容(包含转发、分享)匹配关键字或正则的动态',type: 'c',default: false,move_right: true,},{type: 'br',},{id: 'convertEmojiEnable',label: '表情转成文字',title:'判定时将表情包转换成对应的标识文字,例:[#腿]、[tv_白眼]等\n注意:使用关键字来匹配表情时,必须包含完整的中括号对;\n如 "#腿" 是无法匹配表情 [#腿] 的,需使用 "[#腿]" 进行匹配',type: 'c',default: false,},{id: 'showBlockUserBtnEnable',label: '显示屏蔽用户按钮',title: '在评论在底部显示一个屏蔽该用户的按钮',type: 'c',default: false,move_right: true,},{id: 'showBangBtnEnable',label: '显示"爆炸"按钮',title: '在评论底部显示一个可以拆分并选择文本内容的按钮',type: 'c',default: false,move_right: true,},{type: 'br',},{id: 'messageReplyEnable',label: '消息中心里的回复',title: '扩展作用范围以同时允许屏蔽消息中心里的回复',type: 'c',default: false,},{id: 'messageReplyDelEnable',label: '自动删除回复通知',title: '同时将屏蔽的回复通知自动删除\n删除的记录可在控制台中查看\n请谨慎启用该选项,因为删除操作是不可逆的!',type: 'c',default: false,move_right: true,},{type: 's',},{type: 's',label: '白名单 (用户名):',classname: MODULE.WHITELIST.className,},{id: 'whitelistInput',label: '输入:',placeholder: ' 同时输入多个时以半角逗号分隔 ',type: 'i',list_id: 'whitelistArray',classname: MODULE.WHITELIST.className,},{id: 'whitelistArray',type: 'l',default: [],classname: MODULE.WHITELIST.className,},{type: 's',},{type: 's',label: '黑名单 (用户名/粉丝勋章名):',classname: MODULE.USERNAME.className,},{id: 'usernameInput',label: '输入:',placeholder: ' 同时输入多个时以半角逗号分隔 ',type: 'i',list_id: 'usernameArray',classname: MODULE.USERNAME.className,},{id: 'usernameArray',type: 'l',default: [],classname: MODULE.USERNAME.className,},{type: 's',},{type: 's',label: '视频(或直播间/相薄)关键字或正则:',classname: MODULE.VIDEO_KEYWORD.className,},{id: 'videoKeywordInput',label: '输入:',placeholder: ' 正则表达式格式: /Pattern/Modifier ',type: 'i',list_id: 'keywordArray',classname: MODULE.VIDEO_KEYWORD.className,},{id: 'keywordArray',type: 'l',default: [],classname: MODULE.VIDEO_KEYWORD.className,},{type: 's',},{type: 's',label: '评论(或回复)关键字或正则:',classname: MODULE.COMMENT_KEYWORD.className,},{id: 'commentKeywordInput',label: '输入:',placeholder: ' 正则表达式格式: /Pattern/Modifier ',type: 'i',list_id: 'commentArray',classname: MODULE.COMMENT_KEYWORD.className,},{id: 'commentArray',type: 'l',default: [],classname: MODULE.COMMENT_KEYWORD.className,},{type: 's',},],events: {save: config => {bilibiliConfig = config;hideEvent();},change: config => {bilibiliConfig = config;hideEvent();},},});bilibiliConfig = blockObj.getConfig();hideEvent();try {let observer = new MutationObserver(() => {hideEvent();});observer.observe(document.querySelector('body'), {childList: true,subtree: true,});} catch (e) {console.error(e);}if (/www\.bilibili\.com\/?(\/\?spm_id_from=.*)?$/.test(OLD_URL)) {document.querySelector('.btn.next') &&document.querySelector('.btn.next').addEventListener('click', () => {setTimeout(() => {hideEvent();}, 250);});document.querySelector('.btn.prev') &&document.querySelector('.btn.prev').addEventListener('click', () => {setTimeout(() => {hideEvent();}, 250);});document.body.arrive('.manga-panel .btn-change',{fireOnAttributesModification: true,onceOnly: true,existing: true,},item => {item.addEventListener('click', () => {setTimeout(() => {hideEvent();}, 1000);});});document.body.arrive('.manga-panel .tab-switch-item',{fireOnAttributesModification: true,onceOnly: true,existing: true,},item => {item.addEventListener('click', () => {setTimeout(() => {hideEvent();}, 1000);});});}if (/live\.bilibili\.com\/all/.test(OLD_URL)) {document.body.arrive('.content-panel h1.title > span',{fireOnAttributesModification: true,onceOnly: true,existing: true,},item => {item.addEventListener('click', () => {setTimeout(() => {hideEvent();}, 1000);});});}});function displayDel(panelId, num) {if (document.getElementById(panelId)) {document.getElementById(panelId).textContent = ' (自动删除了 ' + num + ' 条通知)';} else {const delPanel = document.createElement('span');delPanel.id = panelId;delPanel.textContent = ' (自动删除了 ' + num + ' 条通知)';document.querySelector('.space-right-top .title').appendChild(delPanel);}}function decideText(textValue,isComment = false,isLive = false,isPic = false,sourceText = null,isMessageReply = false,dynamicVideo = null,dynamic = null,repost = null) {let isDecide = false;let isDecideComment = false;let isDecideDynamic = false;let isDecideDynamicTitle = false;let isDecideDynamicContent = false;let isDecideDynamicRepost = false;if (bilibiliConfig.functionEnable) {if (textValue) {if (isComment) {if (isMessageReply) {if (bilibiliConfig.messageReplyEnable) {isDecideComment = true;}} else {isDecideComment = true;}} else if (isLive) {if (bilibiliConfig.liveEnable) {isDecide = true;}} else if (isPic) {if (bilibiliConfig.picEnable) {isDecide = true;}} else {isDecide = true;}} else {if (bilibiliConfig.dynamicVideo && dynamicVideo) {isDecideDynamic = true;isDecideDynamicTitle = true;}if (bilibiliConfig.dynamicContent && dynamic) {isDecideDynamic = true;isDecideDynamicContent = true;}if (bilibiliConfig.dynamicContent && repost) {isDecideDynamic = true;isDecideDynamicRepost = true;}}}if (isDecide) {if (bilibiliConfig.keywordEnable) {for (let k of bilibiliConfig.keywordArray) {if (k) {if (typeof k === 'string' && textValue.includes(k)) {return true;} else {try {if (textValue.match(k)) {return true;}} catch (e) {console.error('存在错误的正则表达式: ', e);}}}}}} else if (isDecideComment) {if (bilibiliConfig.commentKeywordEnable) {for (let i of bilibiliConfig.commentArray) {if (i) {if (typeof i === 'string') {if (textValue.includes(i)) {if (sourceText) {if (sourceText.includes(i)) {return true;} else if (/\[.*\]/i.test(i)) {return true;}} else {return true;}} else if (sourceText && /\[.*\]/i.test(i)) {if (sourceText.includes(i)) {return true;}}} else {try {if (textValue.match(i)) {return true;} else if (sourceText.match(i)) {return true;}} catch (e) {console.error('存在错误的正则表达式: ', e);}}}}}} else if (isDecideDynamic) {let dynamicStatus = false;if (isDecideDynamicTitle) {if (bilibiliConfig.keywordEnable) {for (let o of bilibiliConfig.keywordArray) {if (o) {if (typeof o === 'string' && dynamicVideo.includes(o)) {dynamicStatus = true;break;} else {try {if (dynamicVideo.match(o)) {dynamicStatus = true;break;}} catch (e) {console.error('存在错误的正则表达式: ', e);}}}}}}if (!dynamicStatus && dynamic.content && isDecideDynamicContent) {if (bilibiliConfig.commentKeywordEnable) {for (const q of bilibiliConfig.commentArray) {if (q) {if (typeof q === 'string') {if (dynamic.content.includes(q)) {if (dynamic.sourceContent) {if (dynamic.sourceContent.includes(q)) {dynamicStatus = true;break;} else if (/\[.*\]/i.test(q)) {dynamicStatus = true;break;}} else {dynamicStatus = true;break;}} else if (dynamic.sourceContent && /\[.*\]/i.test(q)) {if (dynamic.sourceContent.includes(q)) {dynamicStatus = true;break;}}} else {try {if (dynamic.content.match(q)) {dynamicStatus = true;break;} else if (dynamic.sourceContent.match(q)) {dynamicStatus = true;break;}} catch (e) {console.error('存在错误的正则表达式: ', e);}}}}}}if (!dynamicStatus && repost.content && isDecideDynamicRepost) {if (bilibiliConfig.commentKeywordEnable) {for (const r of bilibiliConfig.commentArray) {if (r) {if (typeof r === 'string') {if (repost.content.includes(r)) {if (repost.sourceContent) {if (repost.sourceContent.includes(r)) {dynamicStatus = true;break;} else if (/\[.*\]/i.test(r)) {dynamicStatus = true;break;}} else {dynamicStatus = true;break;}} else if (repost.sourceContent && /\[.*\]/i.test(r)) {if (repost.sourceContent.includes(r)) {dynamicStatus = true;break;}}} else {try {if (repost.content.match(r)) {dynamicStatus = true;break;} else if (repost.sourceContent.match(r)) {dynamicStatus = true;break;}} catch (e) {console.error('存在错误的正则表达式: ', e);}}}}}}return dynamicStatus;}return false;}function decideUsername(username,isComment = false,isLive = false,isPic = false,isMessageReply = false,trueLove = null,repostUser = null) {let isDecide = false;if (bilibiliConfig.functionEnable && username) {if (isComment) {if (bilibiliConfig.commentEnable) {if (isMessageReply) {if (bilibiliConfig.messageReplyEnable) {isDecide = true;}} else {isDecide = true;}}} else if (isLive) {if (bilibiliConfig.liveEnable) {if (bilibiliConfig.usernameEnable) {isDecide = true;}}} else if (isPic) {if (bilibiliConfig.picEnable) {if (bilibiliConfig.usernameEnable) {isDecide = true;}}} else {if (bilibiliConfig.usernameEnable) {isDecide = true;}}}if (isDecide) {if (bilibiliConfig.usernameArray.includes(username)) {return true;}}if (bilibiliConfig.functionEnable) {if (bilibiliConfig.commentFans && trueLove) {if (bilibiliConfig.usernameArray.includes(trueLove)) {return true;}}if (bilibiliConfig.dynamicVideo && repostUser) {if (bilibiliConfig.usernameArray.includes(repostUser)) {return true;}}}return false;}function isWhitelist(username) {if (username && bilibiliConfig.functionEnable && bilibiliConfig.whitelistEnable) {if (bilibiliConfig.whitelistArray.includes(username)) {return true;}}return false;}function hideHandler(itemNode, username, textValue, method = 0, type = {}) {if (username) {if (typeof username === 'object') {username = username.textContent;}username = username.trim();}if (textValue) {if (typeof textValue === 'object') {textValue = textValue.textContent;}textValue = textValue.trim();}const isComment = type.comment ? true : false;const isMessageReply = type.messageReply ? true : false;const delButton = type.delButton ? type.delButton : null;const isLive = type.live ? true : false;const isPic = type.pic ? true : false;const trueLove = type.trueLove ? type.trueLove.trim() : null;const dynamic = type.dynamic != null && typeof type.dynamic === 'object' ? type.dynamic : null;const dynamicVideo = type.dynamicVideo ? type.dynamicVideo.trim() : null;const repost = type.repost != null && typeof type.repost === 'object' ? type.repost : null;const repostUser = type.repostUser ? type.repostUser.trim() : null;const sourceText = type.sourceText ? type.sourceText : null;let hideStatus = false;if (isWhitelist(username)) {hideStatus = false;} else if (decideUsername(username, isComment, isLive, isPic, isMessageReply, trueLove, repostUser)) {hideStatus = true;} else if (decideText(textValue, isComment, isLive, isPic, sourceText, isMessageReply, dynamicVideo, dynamic, repost)) {hideStatus = true;} else {hideStatus = false;}if (itemNode.constructor == Array) {for (let eleNode of itemNode) {if (eleNode) {Block_Obj.fn.hideOperation(eleNode, hideStatus, method);}}} else {Block_Obj.fn.hideOperation(itemNode, hideStatus, method);}if (hideStatus) {if (delButton) {if (bilibiliConfig.messageReplyDelEnable && !recordButton.includes(delButton)) {recordButton.push(delButton);delButton.click();console.info('%c自动删除通知:', 'color: purple;', '\n用户名:', username, '\n评论内容:', textValue);delNum++;displayDel('messageDelPanel', delNum);}}}}function extractEle(ele, selector) {let r###lt = null;if (selector) {if (Array.isArray(selector)) {for (const e of selector) {if (ele.querySelector(e)) {r###lt = ele.querySelector(e);break;}}} else {r###lt = ele.querySelector(selector);}}return r###lt;}function hideEvent() {handler.forEach(item => {const { c, index, user, text, method, type, userReg, url, comment, bv } = item;let status = false;if (url) {if (Array.isArray(url)) {for (let u of url) {if (OLD_URL.indexOf(u) !== -1) {status = true;break;}}} else {status = OLD_URL.indexOf(url) !== -1;}} else {status = OLD_URL.indexOf('www.bilibili.com') !== -1;}if (status) {const all = document.querySelectorAll(index);for (const ele of all) {if (c == 1) {hideHandler(ele, extractEle(ele, user).textContent.replace(userReg, ''));} else if (c == 2) {const bvNum = getBvNumber(ele.querySelector(bv).href);asyncUsernameHandle(bvNum, ele, extractEle(ele, text));} else {hideHandler(ele, extractEle(ele, user), extractEle(ele, text), method, type);}}if (comment) {hideComment();}}});if (OLD_URL.indexOf('www.bilibili.com') !== -1) {try {const carouselModulePanel = document.querySelector('.carousel-module .panel');if (carouselModulePanel) {const carouselModulePanelTitle = carouselModulePanel.querySelectorAll('ul.title a');const carouselModulePanelPic = carouselModulePanel.querySelectorAll('ul.pic li');const carouselModulePanelTrig = carouselModulePanel.querySelectorAll('ul.trig span');for (let panelIndex = 0; panelIndex < carouselModulePanelTitle.length; panelIndex++) {hideHandler([carouselModulePanelTitle[panelIndex], carouselModulePanelPic[panelIndex], carouselModulePanelTrig[panelIndex]],null,carouselModulePanelTitle[panelIndex],3);}}} catch (e) {console.error('bilibili_BLock: Variable carouselModulePanel is error.');console.error(e);}const rankItem = document.getElementsByClassName('rank-item');for (const rankItemEle of rankItem) {let textValue = '';if (rankItemEle.querySelector('p.ri-title')) {textValue = rankItemEle.querySelector('p.ri-title');}if (rankItemEle.querySelector('a.title')) {textValue = rankItemEle.querySelector('a.title');}if (rankItemEle.querySelector('.detail > a')) {hideHandler(rankItemEle, rankItemEle.querySelector('.detail > a'), textValue);} else if (rankItemEle.querySelector('a')) {const linkA = rankItemEle.querySelector('a');const bvNum = getBvNumber(linkA.href);asyncUsernameHandle(bvNum, rankItemEle, textValue);}}const recentHot = document.querySelectorAll('div#recent_hot li');for (const recentHotItem of recentHot) {const bvNum = getBvNumber(recentHotItem.querySelector('a').href);asyncUsernameHandle(bvNum, recentHotItem, recentHotItem.title);}const bilibiliPlayerRecommendVideo = document.getElementsByClassName('bilibili-player-recommend-video');for (const bilibiliPlayerRecommendVideoItem of bilibiliPlayerRecommendVideo) {const bvNum = getBvNumber(bilibiliPlayerRecommendVideoItem.href);asyncUsernameHandle(bvNum,bilibiliPlayerRecommendVideoItem,bilibiliPlayerRecommendVideoItem.querySelector('.bilibili-player-recommend-title'));}const bilibiliPlayerEndingPanelBoxRecommend = document.querySelectorAll('a.bilibili-player-ending-panel-box-recommend');for (const bilibiliPlayerEndingPanelBoxRecommendItem of bilibiliPlayerEndingPanelBoxRecommend) {let bvNum = '';try {bvNum = /(?:av|bv)(\w+)/i.exec(bilibiliPlayerEndingPanelBoxRecommendItem.getAttribute('data-bvid'))[1];} catch (e) {bvNum = null;}if (!bvNum) {try {bvNum = getBvNumber(bilibiliPlayerEndingPanelBoxRecommendItem.href);} catch (e) {bvNum = null;}}asyncUsernameHandle(bvNum,bilibiliPlayerEndingPanelBoxRecommendItem,bilibiliPlayerEndingPanelBoxRecommendItem.querySelector('.bilibili-player-ending-panel-box-recommend-cover-title'));}} else if (/(t|manga|space)\.bilibili\.com/.test(OLD_URL)) {const card = document.querySelectorAll('div.card');for (const cardItem of card) {const contentFull = cardItem.querySelector('.content-full');let sourceContent = null;let convertText = null;if (contentFull && !contentFull.closest('.repost')) {sourceContent = contentFull.textContent;if (bilibiliConfig.convertEmojiEnable) {convertText = getConvertText(contentFull.innerHTML);}}const title = cardItem.querySelector('.title');let titleText = null;if (title) {titleText = title.textContent;}let repostUser = cardItem.querySelector('.repost .username');repostUser = repostUser ? repostUser.textContent : null;let repostSourceText = null;let repostConvertText = null;const repostContent = cardItem.querySelector('.repost .content-full');if (repostContent) {repostSourceText = repostContent.textContent;if (bilibiliConfig.convertEmojiEnable) {repostConvertText = getConvertText(repostContent.innerHTML);}}if (bilibiliConfig.convertEmojiEnable) {hideHandler(cardItem, null, null, 0, {dynamicVideo: titleText,dynamic: {content: convertText,sourceContent: sourceContent,},repostUser,repost: {content: repostConvertText,sourceContent: repostSourceText,},});} else {hideHandler(cardItem, null, null, 0, {dynamicVideo: titleText,dynamic: {content: sourceContent,},repostUser,repost: {content: repostSourceText,},});}}hideComment();} else if (/message\.bilibili\.com\/#\/reply/.test(OLD_URL)) {const replyItem = document.getElementsByClassName('reply-item');for (const replyItemEle of replyItem) {let nextNode = null;if (replyItemEle.nextElementSibling) {if (replyItemEle.nextElementSibling.classList.contains('divider')) {nextNode = replyItemEle.nextElementSibling;}}const sourceText = replyItemEle.querySelector('.text').textContent;if (bilibiliConfig.convertEmojiEnable) {const convertText = replyItemEle.querySelector('.text span').innerHTML.replace(/<img.*alt="(.*)".*>/g, '$1');hideHandler([replyItemEle, nextNode], replyItemEle.querySelector('.name-field a'), convertText, 0, {comment: true,messageReply: true,sourceText: sourceText,delButton: replyItemEle.querySelector('.bl-button--primary'),});} else {hideHandler([replyItemEle, nextNode], replyItemEle.querySelector('.name-field a'), sourceText, 0, {comment: true,messageReply: true,delButton: replyItemEle.querySelector('.bl-button--primary'),});}}} else if (/live\.bilibili\.com\/\d+/.test(OLD_URL)) {const chatItems = document.querySelectorAll('#chat-items .chat-item');chatItems.forEach(item => {const fansMedalContent = item.querySelector('.fans-medal-content');hideHandler(item, null, null, 0, {trueLove: fansMedalContent ? fansMedalContent.textContent : null,});});}}function hideComment() {const commentList = document.querySelectorAll('.comment-list .list-item');for (const commentListItem of commentList) {const sourceText = commentListItem.querySelector('.con > p.text').textContent;let trueLove = commentListItem.querySelector('.true-love');trueLove = trueLove ? trueLove.firstChild.textContent : null;if (bilibiliConfig.convertEmojiEnable) {const convertText = getConvertText(commentListItem.querySelector('.con > p.text').innerHTML);hideHandler(commentListItem, commentListItem.querySelector('.con > .user a.name'), convertText, 0, {comment: true,sourceText: sourceText,trueLove,});} else {hideHandler(commentListItem, commentListItem.querySelector('.con > .user a.name'), sourceText, 0, {comment: true,trueLove,});}const commentReplyBtn = commentListItem.querySelector('.reply.btn-hover');if (bilibiliConfig.showBlockUserBtnEnable) {commentReplyBtn &&!commentListItem.querySelector('.bilibili_comment_user_block_button') &&commentReplyBtn.after(blockObj.createBlockBtn(commentListItem.querySelector('.con > .user a.name').textContent,'usernameArray','bilibili_comment_user_block_button','span','屏蔽','屏蔽该用户'));} else {commentListItem.querySelector('.bilibili_comment_user_block_button') &&commentListItem.querySelector('.bilibili_comment_user_block_button').remove();}if (bilibiliConfig.showBangBtnEnable) {const commentBtn = commentListItem.querySelector('.bilibili_comment_user_block_button') || commentReplyBtn;commentBtn &&!commentListItem.querySelector('.bilibili_comment_bang_button') &&commentBtn.after(blockObj.createBigBangBtn(sourceText,'commentArray','bilibili_comment_bang_button','span','爆炸','拆分并选择文本内容进行屏蔽'));} else {commentListItem.querySelector('.bilibili_comment_bang_button') &&commentListItem.querySelector('.bilibili_comment_bang_button').remove();}}const replyCommentList = document.querySelectorAll('.comment-list .reply-item');for (const replyCommentListItem of replyCommentList) {const replySourceText = replyCommentListItem.querySelector('.reply-con .text-con').textContent;if (bilibiliConfig.convertEmojiEnable) {const replyConvertText = getConvertText(replyCommentListItem.querySelector('.reply-con .text-con').innerHTML);hideHandler(replyCommentListItem, replyCommentListItem.querySelector('.reply-con .user a.name'), replyConvertText, 0, {comment: true,sourceText: replySourceText,});} else {hideHandler(replyCommentListItem, replyCommentListItem.querySelector('.reply-con .user a.name'), replySourceText, 0, {comment: true,});}const replyBtn = replyCommentListItem.querySelector('.reply.btn-hover');if (bilibiliConfig.showBlockUserBtnEnable) {replyBtn &&!replyCommentListItem.querySelector('.bilibili_reply_user_block_button') &&replyBtn.after(blockObj.createBlockBtn(replyCommentListItem.querySelector('.reply-con .user a.name').textContent,'usernameArray','bilibili_reply_user_block_button','span','屏蔽','屏蔽该用户'));} else {replyCommentListItem.querySelector('.bilibili_reply_user_block_button') &&replyCommentListItem.querySelector('.bilibili_reply_user_block_button').remove();}if (bilibiliConfig.showBangBtnEnable) {const pBtn = replyCommentListItem.querySelector('.bilibili_reply_user_block_button') || replyBtn;pBtn &&!replyCommentListItem.querySelector('.bilibili_reply_bang_button') &&pBtn.after(blockObj.createBigBangBtn(replySourceText,'commentArray','bilibili_reply_bang_button','span','爆炸','拆分并选择文本内容进行屏蔽'));} else {replyCommentListItem.querySelector('.bilibili_reply_bang_button') &&replyCommentListItem.querySelector('.bilibili_reply_bang_button').remove();}}}function getConvertText(text) {return text.replace(/<img.*?alt="(.*?)".*?>/g, '$1').replace(/<a.*?>(.*?)<\/\s*a>/g, '$1').replace(/ /g, ' ');}function asyncUsernameHandle(bvNum, mainEle, textValue, hideMethod = 0, typeInfo = {}) {let userName = '';if (bvNum) {let recordUser = false;infoRecord.forEach(item => {if (item.bv == bvNum) {userName = item.user;recordUser = true;}});if (recordUser) {hideHandler(mainEle, userName, textValue, hideMethod, typeInfo);} else {infoRecord.push({bv: bvNum,user: userName,time: dayjs().format('YYYY-MM-DD'),});const apiUrl = bvNum.match(/^\d+$/)? 'https://api.bilibili.com/x/web-interface/view?aid=': 'https://api.bilibili.com/x/web-interface/view?bvid=';const xhr = new XMLHttpRequest();xhr.open('GET', apiUrl + bvNum, true);xhr.responseType = 'json';xhr.onload = () => {if (xhr.status == 200) {if (xhr.response.data && xhr.response.data.owner && xhr.response.data.owner['name']) {userName = xhr.response.data.owner['name'];}} else {sendStatus = false;console.info(apiUrl + bvNum + '\nresponse status: ' + xhr.status);}hideHandler(mainEle, userName, textValue, hideMethod, typeInfo);infoRecord.forEach(item => {if (item.bv == bvNum) {item.user = userName;}});Block_Obj.GM.setValue('infoRecord', infoRecord);};xhr.onerror = () => {console.info(apiUrl + bvNum + '\nerror.');hideHandler(mainEle, userName, textValue, hideMethod, typeInfo);};setTimeout(() => {sendStatus && xhr.send();}, INTERVAL_TIME * requestTotal);requestTotal++;}} else {hideHandler(mainEle, userName, textValue, hideMethod, typeInfo);}}function getBvNumber(video_link) {let bvNum = '';try {bvNum = /\/video\/(?:av|bv)(\w+)/i.exec(video_link)[1];} catch (e) {bvNum = null;}return bvNum;}})();