// ==UserScript== // @name BiliBili Tags Blocker // @namespace http://tampermonkey.net/ // @version 0.1 // @description 眼不见为净,耳不听为清,心不想则静 // @author xiaoxi // @license MIT // @include *://www.bilibili.com/* // @include *://search.bilibili.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=bilibili.com // @require https://cdn.bootcdn.net/ajax/libs/jquery/2.2.4/jquery.min.js // @require https://greasyfork.org/scripts/407543-block-obj/code/Block_Obj.js?version=963893 // @grant GM_xmlhttpRequest // @grant unsafeWindow // @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 // @downloadURL none // ==/UserScript== // https://greasyfork.org/zh-CN/scripts/417760-checkjquery var BiliBiliTagsBlocker = { functionEnable: true, tagsArray: [], }; const BASIC_STYLE = ` .block_obj_checkbox_label { padding-left: 13px; } `; let blockObj = new Block_Obj('BiliBili_Tags_Blocker'); function initSettingUI(){ blockObj.init({ id: 'BiliBiliTagsBlocker', menu: 'Tags屏蔽设置', style: BASIC_STYLE, field: [ { id: 'functionEnable', label: '启用屏蔽功能', title: '总开关', type: 'c', default: true, }, { label: 'Tag设置', type: 's', }, { id: 'tagInput', label: '输入:', placeholder: ' 同时输入多个时以英文逗号分隔 ', type: 'i', list_id: 'tagsArray', //classname: MODULE.WHITELIST.className, }, { id: 'tagsArray', type: 'l', default: [], //classname: MODULE.WHITELIST.className, }, ], events: { save: config => { BiliBiliTagsBlocker = config; }, change: config => { BiliBiliTagsBlocker = config; }, }, }); } var scrollTop = 0; //视频信息 var videoInfo = []; var oldVideoInfo = []; var isLoading = false; let href = location.href; let matchSearch = href.match(/search.bilibili/); let matchPopular = href.match(/popular/); //=======================通用========================= //当前搜索区域id var currentSectionId; //获取视频信息 function initvideoInfo(match) { let loaded = 0; if(match == "popular"){ let videoCardList = $(".video-card__content"); videoCardList.each(function(i){ let href = $(this).children("a").attr("href"); let bvInfo = { bv : getBvcountber(href), index : i } loaded++; videoInfo.push(bvInfo); }); // let videoCardInfoList = $(".video-card__info"); //videoCardInfoList.each(function(i){ // let title = $(this).children("p").attr("title"); // videoInfo[i]["title"]=title; // }); console.log(videoInfo); } if(match == "search"){ //let videoCardList = $("li.video-item"); let videoCardList = $(".video-item"); videoCardList.each(function(i){ let href = $(this).children("a").attr("href"); let title; let isBanner; if($(this).children("a").attr("title") != undefined) { title = $(this).children("a").attr("title"); isBanner = false; } else{ var t = $(this).children("a").context.innerText.split("\n"); title = t[1]; isBanner = true; } let bvInfo = { bv : getBvcountber(href), index : i, title : title, isBanner : isBanner, context : $(this) } loaded++; videoInfo.push(bvInfo); }); } return new Promise(function (isLoad) { let checkvideoInfo = setInterval(function () { $.each(videoInfo, function(i, v){ if(loaded == videoInfo.length){ clearInterval(checkvideoInfo); isLoad(true); } }); }, 500); }); } //获取视频Tag信息 function initVideoTagInfo() { let loaded = false; $.each(videoInfo, function(i, b){ $.ajax("https://api.bilibili.com/x/web-interface/view/detail/tag?bvid=BV"+b.bv, { method: 'GET', headers: { "content-type": "application/json" }, async: true, success: function (tags) { let tagInfo = { tags : tags } b["Tags"] = tagInfo; let r = { isRemove : false } b["isRemove"] = r; }, }); }); return new Promise(function (isLoad) { let checkTagsInfo = setInterval(function () { $.each(videoInfo, function(i, v){ if (v.hasOwnProperty("Tags") && v.Tags.hasOwnProperty("tags") && videoInfo[0].hasOwnProperty("isRemove")) { if (v.Tags.tags.hasOwnProperty("data")) { if(i == videoInfo.length-1){ clearInterval(checkTagsInfo); isLoad(true); } } } }); }, 500); }); } //设置需要删除的视频 function setRemoveVideo(){ let loaded = 0; $.each(videoInfo, function(i, v){ loaded++; if (v.hasOwnProperty("Tags") && v.Tags.hasOwnProperty("tags") && videoInfo[0].hasOwnProperty("isRemove")) { if (v.Tags.tags.hasOwnProperty("data") && v.Tags.tags.data.length > 0) { $.each(v.Tags.tags.data, function(i, t){ $.each(BiliBiliTagsBlocker.tagsArray, function(i, bt){ if(bt == t.tag_name){ let r = { isRemove : true } v["isRemove"] = r; } }); }); } } }); return new Promise(function (isLoad) { let checkTagsInfo = setInterval(function () { if (videoInfo.length == loaded) { clearInterval(checkTagsInfo); isLoad(true); } }, 500); }); } //删除网页中的视频 function removeVideo(match){ let Removed = 1; $.each(videoInfo, function(i, v){ if(v.hasOwnProperty("isRemove") && v.isRemove.hasOwnProperty("isRemove") && v.isRemove.isRemove && oldVideoInfo != videoInfo){ if(match == "popular"){ $(".video-card:nth-of-type("+(v.index+Removed)+")").remove(); console.log((v.index+Removed)+" "+ v.bv+ " "+Removed); Removed--; } if(match == "search"){ v.context.css({"display":"none"}); //v.context.css({"background":"blue"}) } } }); } //视频板块监听器 function initBodyContainListener(){ var targetNode = $('.body-contain')[0]; //options:监听的属性 var options = {childList: true,attributes :true}; //回调事件 console.log("init 板块监听"); function callback(mutationsList, observer) { if(currentSectionId != $(".body-contain").children("div").attr("id")) { currentSectionId = $(".body-contain").children("div").attr("id"); console.log("搜索区域变为"+currentSectionId); //console.log("板块监听 callback"); initSearchSectionListener(); initSearchListener() if(currentSectionId == "all-list" || currentSectionId == "video-list"){ setTimeout(function(){ oldVideoInfo = videoInfo; videoInfo = []; //SearchLoading() initvideoInfo("search").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { //console.log(videoInfo); removeVideo("search") //stopSearchLoading() }); }); }); },1200); } } } let mutationObserver = new MutationObserver(callback); let checkTarget = setInterval(function () { currentSectionId = $(".body-contain").children("div").attr("id"); console.log("等待搜索区域"); targetNode = $('.body-contain')[0]; if(targetNode != undefined && targetNode != null && currentSectionId != undefined){ mutationObserver.observe(targetNode, options); console.log("搜索区域变为"+currentSectionId); // initSearchLoading() BUG initSearchSectionListener(); initSearchListener() //SearchLoading() BUG setTimeout(function(){ oldVideoInfo = videoInfo; videoInfo = []; initvideoInfo("search").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { //console.log(videoInfo); removeVideo("search") // stopSearchLoading() BUG }); }); }); },500); clearInterval(checkTarget); } }, 500); } //=======================热门页面========================= //设置监听器,监听新加载的视频 function initPopularListener(){ var targetNode = $('.card-list')[0]; //options:监听的属性 var options = {childList: true,subtree:true}; //回调事件 function callback(mutationsList, observer) { if(mutationsList[0].addedNodes.length!=0 && videoInfo.length>=20 && isLoading == false){ isLoading = true; oldVideoInfo = videoInfo; scrollTop = $(document).scrollTop(); Loading(); $(document).scrollTop(0); videoInfo = []; initvideoInfo("popular").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { removeVideo("popular"); //console.log(videoInfo); stopLoading() scrollTop = $(document).scrollTop(scrollTop); isLoading = false; }); }); }); } } var mutationObserver = new MutationObserver(callback); mutationObserver.observe(targetNode, options); } //初始化加载动画 function initLoading(){ let g_loadingImage = 'https://pp-1252089172.cos.ap-chengdu.myqcloud.com/loading.gif'; $('.popular-list').prepend('
'); $("head").append(''); $(".card-list").css({'display': 'none'}); $(document).scrollTop(0); } //进行加载动画 function Loading(){ $("#loading").css({'display': 'block'}); $(".card-list").css({'display': 'none'}); $(document).scrollTop(0); } //停止加载动画 function stopLoading(){ $("#loading").css({'display': 'none'}); $(".card-list").css({'display': 'flex'}); $(document).scrollTop(scrollTop) } //==================搜索页面======================= function disConnectListener(){ console.log(33333333333); //videoListListener.disconnect(); } //初始化加载动画 function initSearchLoading(){ let g_loadingImage = 'https://pp-1252089172.cos.ap-chengdu.myqcloud.com/loading.gif'; $('.body-contain').children("div").prepend('
'); //$("head").append(''); $(".video-list").css({'display': 'none'}); //$(document).scrollTop(0); } //进行加载动画 function SearchLoading(){ $("#loadingSearch").css({'display': 'block'}); $(".video-list").css({'display': 'none'}); //$(document).scrollTop(0); } //停止加载动画 function stopSearchLoading(){ $("#loadingSearch").css({'display': 'none'}); $(".video-list").css({'display': 'block'}); //$(document).scrollTop(scrollTop) } //页码监听 function initSearchListener(){ var targetNode = $('.flow-loader')[0]; //options:监听的属性 var options = {childList: true,attributes :true}; //回调事件 console.log("init 页码监听"); function callback(mutationsList, observer) { if(mutationsList[0].addedNodes.length!=0 && videoInfo.length>=20 && isLoading == false) { console.log("页码监听 callback"); initSearchSectionListener() let c = []; $.each(mutationsList, function(i, m){ if(m.addedNodes[0] != undefined && m.addedNodes[0] != null){ if(m.addedNodes[0].className != undefined && m.addedNodes[0].className != null){ c = m.addedNodes[0].className.split(" ") } } if(m.addedNodes[0] != undefined && m.addedNodes[0].previousSibling != undefined && c.includes("video-list")){ isLoading = true; oldVideoInfo = videoInfo; videoInfo = []; //SearchLoading() BUG initvideoInfo("search").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { removeVideo("search") //stopSearchLoading() BUG isLoading = false; }); }); }); } }); } } var mutationObserver = new MutationObserver(callback); let checkTarget = setInterval(function () { if(targetNode != undefined && targetNode != null){ mutationObserver.observe(targetNode, options); clearInterval(checkTarget); } }, 500); } //选项监听 function initSearchSectionListener(){ var targetNode = $('.video-list')[0]; //options:监听的属性 var options = {childList: true,attributes :true}; //回调事件 console.log("init 选项监听"); function callback(mutationsList, observer) { console.log("选项监听 callback"); oldVideoInfo = videoInfo; videoInfo = []; initvideoInfo("search").then(function (resolve) { // SearchLoading() BUG initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { //console.log(videoInfo); removeVideo("search") //stopSearchLoading() BUG }); }); }); } let mutationObserver = new MutationObserver(callback); let checkTarget = setInterval(function () { if(targetNode != undefined && targetNode != null){ mutationObserver.observe(targetNode, options); clearInterval(checkTarget); } }, 500); } //通过url获得BV号 function getBvcountber(video_link) { let bvcount = ''; try { bvcount = /\/video\/(?:av|bv)(\w+)/i.exec(video_link)[1]; } catch (e) { bvcount = null; } return bvcount; } //检查jQuery var checkJQuery = function () { let jqueryCdns = [ 'http://code.jquery.com/jquery-2.1.4.min.js', 'https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js', 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js', 'https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js', 'https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js', ]; function isJQueryValid() { try { let wd = unsafeWindow; if (wd.jQuery && !wd.$) { wd.$ = wd.jQuery; } $(); return true; } catch (exception) { return false; } } function insertJQuery(url) { let script = document.createElement('script'); script.src = url; document.head.appendChild(script); return script; } function converProtocolIfNeeded(url) { let isHttps = location.href.indexOf('https://') != -1; let urlIsHttps = url.indexOf('https://') != -1; if (isHttps && !urlIsHttps) { return url.replace('http://', 'https://'); } else if (!isHttps && urlIsHttps) { return url.replace('https://', 'http://'); } return url; } function waitAndCheckJQuery(cdnIndex, resolve) { if (cdnIndex >= jqueryCdns.length) { iLog.e('无法加载 JQuery,正在退出。'); resolve(false); return; } let url = converProtocolIfNeeded(jqueryCdns[cdnIndex]); iLog.i('尝试第 ' + (cdnIndex + 1) + ' 个 JQuery CDN:' + url + '。'); let script = insertJQuery(url); setTimeout(function () { if (isJQueryValid()) { iLog.i('已加载 JQuery。'); resolve(true); } else { iLog.w('无法访问。'); script.remove(); waitAndCheckJQuery(cdnIndex + 1, resolve); } }, 100); } return new Promise(function (resolve) { if (isJQueryValid()) { iLog.i('已加载 jQuery。'); resolve(true); } else { iLog.i('未发现 JQuery,尝试加载。'); waitAndCheckJQuery(0, resolve); } }); } let checkSetting = setInterval(function () { BiliBiliTagsBlocker = blockObj.getConfig(); if(BiliBiliTagsBlocker.tagsArray != null){ //console.log(BiliBiliTagsBlocker.tagsArray); clearInterval(checkSetting); } }, 500); function ILog() { this.prefix = ''; this.v = function (value) { if (level <= this.LogLevel.Verbose) { console.log(this.prefix + value); } } this.i = function (info) { if (level <= this.LogLevel.Info) { console.info(this.prefix + info); } } this.w = function (warning) { if (level <= this.LogLevel.Warning) { console.warn(this.prefix + warning); } } this.e = function (error) { if (level <= this.LogLevel.Error) { console.error(this.prefix + error); } } this.d = function (element) { if (level <= this.LogLevel.Verbose) { console.log(element); } } this.setLogLevel = function (logLevel) { level = logLevel; } this.LogLevel = { Verbose: 0, Info: 1, Warning: 2, Error: 3, }; let level = this.LogLevel.Verbose; } let inChecking = false; let jqItv = setInterval(function () { if (inChecking) { return; } inChecking = true; checkJQuery().then(function (isLoad) { if (isLoad) { initSettingUI() if (matchSearch) { //initSearchLoading() initBodyContainListener(); initSearchListener(); initSearchSectionListener(); initvideoInfo("search").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { //console.log(videoInfo); removeVideo("search") //stopSearchLoading() }); }); }); } if (matchPopular) { initLoading(); initPopularListener() initvideoInfo("popular").then(function (resolve) { initVideoTagInfo().then(function (resolve) { setRemoveVideo().then(function (resolve) { removeVideo("popular") }); }); }); } clearInterval(jqItv); } inChecking = false; }); }, 1000); var iLog = new ILog();