Bilibili Blacklist

不可关闭的默认屏蔽首页广告,并在左下角添加了屏蔽词功能,能自定义每个屏蔽词的范围(真的会有人需要这种自定义吗)

当前为 2023-06-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Bilibili Blacklist
// @namespace    http://tampermonkey.net/
// @version      0.7.5
// @description  不可关闭的默认屏蔽首页广告,并在左下角添加了屏蔽词功能,能自定义每个屏蔽词的范围(真的会有人需要这种自定义吗)
// @author       Aporia
// @match        *://*.bilibili.com/*
// @icon         https://www.google.com/s2/favicons?domain=google.cn
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addElement
// @grant        GM_xmlhttpRequest
// @require      https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js
// @run-at document-end
// @license MIT

// ==/UserScript==


(function() {
    // Define page types
    let pageTypes = ['searchPage', 'mainPage', 'leaderboard', 'timeLine', 'recommand', 'reply'];
    let pageTypesCN = {searchPage : '搜索页面', mainPage : '主页面', leaderboard: '排行榜', timeLine: '动态', recommand: '推荐', reply: '回复'};

    // Initialize blacklist with some default values
    let blacklist = GM_getValue('blacklist');
    if (blacklist === undefined) {
        blacklist = [{
            keyword: "原神",
            searchPage: true,
            mainPage: true,
            leaderboard: true,
            timeLine: true,
            recommand: true,
            reply: true
        }];
        GM_setValue('blacklist', JSON.stringify(blacklist));
    } else {
        // Parse the stored JSON string back to a JavaScript object
        blacklist = JSON.parse(blacklist);
    }

    let block_blacklist = function(){

        // Block AD
        $("svg.bili-video-card__info--ad").parents("div.bili-video-card").hide();
        $("svg.bili-video-card__info--ad").parents("div.feed-card").hide();

        blacklist.forEach(function(entry){
            let containsString = ":contains('" + entry.keyword + "')";

            // Block search page
            if (entry.searchPage) {
                $("div.bili-video-card__info--right" + containsString).parents('div.bili-video-card:not(.is-rcmd)').hide();
                $("div.media-card-content" + containsString).parents('div.media-card').hide();
            }

            // Block main page
            if (entry.mainPage) {
                $("div.bili-video-card__info--right" + containsString).parents("div.bili-video-card.is-rcmd").hide();
                $("div.bili-video-card__info--right" + containsString).parents("div.feed-card").hide();
                $("div.bili-video-card__info--right" + containsString).parents("div.floor-single-card").hide();
            }

            // Block leaderboard
            if (entry.leaderboard) {
                $("div.video-card__info" + containsString).parents("div.video-card").hide();
            }

            // Block timeline pages
            if (entry.timeLine) {
                $("div.bili-dyn-content" + containsString).parents("div.bili-dyn-list__item").hide();
            }

            // Block recommands
            if (entry.recommand) {
                $("div.info" + containsString).parents("div.video-page-card-small").hide();
            }

            // Block reply
            if (entry.reply) {
                $("div.root-reply" + containsString).parents("div.content-warp").hide();
                $("span.reply-content-container.sub-reply-content" + containsString).parents("div.sub-reply-item").hide();
            }
        });
    }

    // Create the floating "B" button
    let buttonB = $('<button>', {
        text: '屏蔽',
        css: {
            position: 'fixed',
            bottom: '20px',
            left: '20px',
            zIndex: 9999,
            backgroundColor: 'gray',
            color: 'white',
            borderRadius: '8px',
            padding: '10px',
            border: '2px solid white'
        },
        click: function() {
            let keyword = prompt('输入屏蔽关键词:');
            if (keyword) {
                // Add the keyword with all pages selected by default
                blacklist.push({
                    keyword: keyword,
                    searchPage: true,
                    mainPage: true,
                    leaderboard: true,
                    timeLine: true,
                    recommand: true,
                    reply: true
                });

                // Save the updated blacklist to GM storage
                GM_setValue('blacklist', JSON.stringify(blacklist));

                block_blacklist();
            }
        }
    });

    // Create the floating "E" button
    let buttonE = $('<button>', {
        text: '屏蔽词管理',
        css: {
            position: 'fixed',
            bottom: '20px',
            left: '80px',
            zIndex: 9999,
            backgroundColor: 'gray',
            color: 'white',
            borderRadius: '8px',
            padding: '10px',
            border: '2px solid white'
        },
        click: function() {
            if ($('#modal').length > 0) {
                $('#modal').remove();
                return;
            }

            // Build a custom modal dialog
            let modal = $('<div>', {
                id: 'modal',
                css: {
                    position: 'fixed',
                    width: '700px',
                    height: '400px',
                    top: '50%',
                    left: '50%',
                    transform: 'translate(-50%, -50%)',
                    backgroundColor: '#fff',
                    padding: '20px',
                    zIndex: 9999,
                    overflowY: 'auto',
                    border: '2px solid #000'
                }
            });

            // Add title
            let title = $('<h2>', {
                text: '屏蔽词管理',
                css: {
                    textAlign: 'center',
                    margin: '20px 0'
                }
            });

            modal.append(title);

            // Add exit button
            let exitButton = $('<button>', {
                text: '❌',
                css: {
                    position: 'absolute',
                    top: '10px',
                    right: '10px'
                },
                click: function() {
                    modal.remove();
                }
            });

            modal.append(exitButton);

            // Add each keyword to the modal with a '➖' button and checkboxes for each page type
            blacklist.forEach(function(entry, index) {
                let keyword = $('<span>', {
                    text: entry.keyword,
                    css: {
                        display: 'inline-block',
                        width: '100px',
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                        whiteSpace: 'nowrap',
                        verticalAlign: 'middle'
                    }
                });

                let item = $('<div>', {
                    css: {
                        marginBottom: '10px'
                    }
                });

                item.append(keyword);

                let removeButton = $('<button>', {
                    text: '➖',
                    css: {
                        marginLeft: '10px'
                    },
                    click: function() {
                        // Get the keyword of the current item
                        let currentKeyword = entry.keyword;

                        // Filter out the item with the current keyword
                        blacklist = blacklist.filter(function(item) {
                            return item.keyword !== currentKeyword;
                        });

                        // Save the updated blacklist to GM storage
                        GM_setValue('blacklist', JSON.stringify(blacklist));

                        // Remove this keyword from the modal
                        item.remove();

                        block_blacklist();
                    }
                });

                item.append(removeButton);

                // Add a checkbox for each page type
                pageTypes.forEach(function(pageType) {
                    let checkbox = $('<input>', {
                        type: 'checkbox',
                        checked: entry[pageType],
                        change: function() {
                            // Update the blacklist when a checkbox is toggled
                            entry[pageType] = this.checked;
                            GM_setValue('blacklist', JSON.stringify(blacklist));
                            block_blacklist();
                        }
                    });

                    let label = $('<label>', {
                        text: pageTypesCN[pageType],
                        css: {
                            marginLeft: '10px'
                        }
                    });

                    label.prepend(checkbox);
                    item.append(label);
                });

                modal.append(item);
            });

            // Add save button
            let saveButton = $('<button>', {
                text: '✔️',
                css: {
                    display: 'block',
                    margin: '0 auto',
                    marginTop: '10px'
                },
                click: function() {
                    modal.remove();
                    location.reload(); // refresh the page
                }
            });

            modal.append(saveButton);

            $('body').append(modal);
        }
    });

    $('body').append(buttonB);
    $('body').append(buttonE);

    // Run the initial blacklist block
    block_blacklist();

    $('<style>').prop('type', 'text/css').html('.recommended-container_floor-aside .container>*:nth-of-type(n + 8) {margin-top: 0px !important;}').appendTo('head');


    document.addEventListener('DOMNodeInserted', function() {
        block_blacklist();
    }, false);
})();