Greasy Fork is available in English.

爱卡小助手

自动切换经典版和提供黑名单功能。

// ==UserScript==
// @name         爱卡小助手
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  自动切换经典版和提供黑名单功能。
// @author       bg7lgb@gmail.com
// @match        https://www.xcar.com.cn/bbs/*
// @require      https://cdn.bootcss.com/jquery/3.4.1/jquery.slim.min.js
// @grant        GM_addStyle
// ==/UserScript==

// ChangeLog:
// ------------------------------------------------------------
// 2019-10-7 v1.3 修复了刚刚一个手误
// 2019-10-7 v1.2 增加帖子回复过滤
// 2019-10-7 v1.1 修复打开帖子详情页后,无法加载黑名单列表的BUG
// ------------------------------------------------------------

// Todo
// ------------------------------------------------------------
// * 增加详情页中,回复内容的过滤功能
//
// 备注
// ------------------------------------------------------------
// 针对新版界面做过滤,看最下面的nodelistener相关
// 已经可以实现了,修改下面的代码就可以了

(function() {
    'use strict';

//     var $ = unsafeWindow.jQuery;

    const myScriptStyle =
          '.black-btn{height:36px;line-height:36px;text-align:center;color:#ccc}.black-btn.in-black{color:#000}.black-sidebar{position:fixed;width:240px;background:#2d303a;font-size: 16px;top:10%;right:0; border-radius:0 0 0 20px;padding:20px 20px 20px 0;z-index:999;transform:translate3d(100%,0,0);transition:transform .4s ease-out}.black-sidebar-show{transform:translate3d(0,0,0)}.hide-icon{display:none}.black-sidebar-show .hide-icon{display:initial}.black-sidebar-show .show-icon{display:none}.toggle{width:50px;padding:5px;background:#2d303a;position:absolute;top:0;left:-60px;color:#fff;border-radius:10px 0 0 10px;cursor:pointer}.black-sidebar ul{height:180px;padding-left:0;overflow-y:auto;overflow-x:hidden;margin:10px 0}.black-sidebar p{padding-left:20px;color:#0ebeff}.black-sidebar ul::-webkit-scrollbar{width:5px;height:5px}.black-sidebar ul::-webkit-scrollbar-thumb{background:rgba(220,220,220,0.5);border-radius:5px}.black-sidebar ul::-webkit-scrollbar-track{background:#201c29}.black-sidebar li{width:80%;font-size:16px;line-height:26px;color:#fff;font-weight:bold;list-style:none;cursor:pointer;padding-left:50px;position:relative;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.black-sidebar li:hover{background:#000}.black-sidebar li:hover::after{content:"删除";position:absolute;left:10px;font-size:12px;color:#ffdd40}.input-box input{width:82%;border:1px solid rgba(220,220,220,0.4);color:#fff;font-size:16px;line-height:26px;border-radius:4px;background:#262830;margin:5px 0 5px 22px;padding:0 5px}.btn-box{text-align:center}.btn-box span{color:#47cf73;cursor:pointer;margin:0 15px}';
    GM_addStyle(myScriptStyle);

    let authorBlackList ;
    
    //let isNewStyle = true;

    let isNewStyle = checkBBSStyle();

    // 切换回经典版
    if (isNewStyle) switchToClassicStyle();

    addBlackListSidebar();
    addBlackListBtn();

    const pathname = location.pathname.split('/')[1];
    // 原来打算把过滤的按钮加在用户页面,不影响主界面的布局,
    // 后来发现localStorage的跨域问题搞不定,只好把拉黑做到主界面帖子列表的时间栏上
    if (pathname === 'bbs') {
        // 论坛,过滤帖子
        console.log('过滤帖子');
        filterArticle();
    }

    // 检查当前版面的版本, true: new style, false: classic style
    function checkBBSStyle() {
        let items = $('.back_old_link');
        if (items.length > 0) {
            // 找到对应链接
            if (items[0].innerText.trim() == '返回经典版') {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    // 创建黑名单侧栏
    function addBlackListSidebar() {
        const sidebarHtml =
              '<div class="black-sidebar"><div class="toggle">小助手<span class="show-icon"></span><span class="hide-icon"><</span></div><div class="author"><p>作者</p><ul></ul></div><div class="input-box"><input type="text" /></div><div class="btn-box"><span data-type="author">+作者</span></div></div>';
        $('body').append($(sidebarHtml));
        $('.toggle').click(function() {
            $('.black-sidebar').toggleClass('black-sidebar-show');
        });
        updateSidebarList();
        

        // 黑名单删除点击处理
        $('.black-sidebar ul').on('click', 'li', function() {
            const item = $(this);
            blackAction('delete', item.data('type'), item.text());
            //item.remove();
        });

        // 手工输入黑名单
        $('.black-sidebar .btn-box span').click(function() {
            const input = $('.black-sidebar input');
            const value = $.trim(input.val());
            if (!value) return;
            const item = $(this);
            blackAction('add', item.data('type'), value);
            input.val('');
        });

    }

    // 更新侧栏黑名单的显示
    function updateSidebarList() {
        getBlackListFromLocalStorage();
        console.log('updateSidebarList length ' + authorBlackList.length);
        if (authorBlackList.length == 0) {
            console.log('空黑名单');
            $('.black-sidebar .author ul').empty()
            return;
        }
        const authorLi = authorBlackList.map(
            item => `<li data-type="author">${item}<li>`
        );
//         console.log(authorLi);

        $('.black-sidebar .author ul')
            .empty()
            .append(authorLi);

        filterArticle();
    }

    function getBlackListFromLocalStorage() {
        authorBlackList = JSON.parse(
            localStorage.getItem('authorBlackList') || '[]'
        );
    }

    // 添加拉黑按钮
    function addBlackListBtn() {
        if (isNewStyle) {
        } else {
            // 经典版
            console.log('classic style add button');
            let items = $('span.tdate');
            $('span.tdate').on('click', defriend);
        }

        // 添加黑名单
        function defriend() {

            let author;

            if (isNewStyle) {
            } else {
                // 经典版获取用户名
                author = this.previousElementSibling.innerText;

            }
            let arrIndex = authorBlackList.indexOf(author);
            let isInBlack = arrIndex >= 0;
            if (isInBlack) {
                // 已存在黑名单中,删除(其实不起作用,因为看不到)
                blackAction('delete', 'author', author, arrIndex);
            } else {
                // 添加黑名单
                blackAction('add', 'author', author);
            }
        }
    }

    // 黑名单添加和删除
    function blackAction(action, type, name, delIndex) {
        //const list = type === 'author' ? authorBlackList : keywordsBlackList;
        let list = authorBlackList;

        if (action === 'add') {
            if (list.indexOf(name) == -1) {
                list.push(name);
            }
        } else {
            const index = delIndex || list.indexOf(name);
//             console.log('del black , index '+ index);
//             console.log('list before del '+list);
            list.splice(index, 1);
//             console.log('list after del '+list);
        }
//         console.log(list);
        localStorage.setItem(`${type}BlackList`, JSON.stringify(list));
        updateSidebarList();
    }

    function getAuthor() {
        const authorBox = $('span.name');
        const author = authorBox.length ? authorBox[0].innerText : '';
        return author;
    }

    // 过滤帖子
    function filterArticle() {
        console.log('isNewStyle ' + isNewStyle);
        let container;

        if (isNewStyle) {
            container = $('.forum_left_item')[0];
        }else{
            container = $('.post-list')[0];
        }

        let list;
        const config = {
            childList: true,
            subtree: true
        };
        const handleLoad = mutationsList => {
            console.log('handleLoad running');
            for (let mutation of mutationsList) {
                let type = mutation.type;
                let addedNodes = mutation.addedNodes;
                console.log(addedNodes);
                console.log('mutations catch');
                switch (type) {
                    case 'childList':
                        console.log(addedNodes);
                        if (addedNodes.length > 0) {
                        }
                        break;
                }
            }
        };

        const updateLoad = mutationsList => {
            for (let mutation of mutationsList) {
                let type = mutation.type;
                let addedNodes = mutation.addedNodes;
                switch (type) {
                    case 'childList':
                        if (addedNodes.length > 0) {
                            filter($(addedNodes));
                        }
                        break;
                }
            }
        };

        filterStatic();
//         const loadObserver = createNodeListener(
//             container,
//             config,
//             handleLoad
//         );

        function filterStatic() {
            // 过滤静态页面,对新版本的首页和经典版本的适用
            
//             console.log(authorBlackList);
            for (let i in authorBlackList){
//                 console.log(authorBlackList[i]);
                if (isNewStyle) {
                    // Todo:新版页面,未完成
                } else {
                    // 去掉通栏广告
                    let ads = $('div.sticker1200x60');

                    for (let l = 0; l<ads.length; l++) {
                        ads[l].style.display = 'none';
//                         console.log('去除通栏广告');
                    }

                    let pathname = location.pathname.split('/')[2];

                    if (pathname == 'forumdisplay.php') {
                        // 论坛首页

                        // 检查发帖人,在黑名单中则过滤其帖子
                        let posts = $('a.linkblack');
                        for (let j in posts){
                            if (posts[j].innerText == authorBlackList[i]) {
                                 posts[j].parentNode.parentNode.style.display = 'none';
                                 console.log('过滤 ' + authorBlackList[i] +  ' 的主题');
                            }
                        }
                    } else if (pathname == 'viewthread.php') {
                        // 帖子内容及回复页面
                        let users = $('p.name');
//                         console.log('users length '+users.length);
                        for (let k in users) {
                            if (users[k].firstChild == undefined ) {
                                continue;
                            }
//                             console.log(users[k].firstChild);
//                             console.log(users[k].firstChild.innerText);
                            if (users[k].firstChild.innerText == authorBlackList[i]) {
                                users[k].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = 'none';
                                console.log('过滤 ' + authorBlackList[i] +  ' 的帖子');
                            }
                        }
                    } else {
                        console.log('filterStatic 未知页面');
                        return ;
                    }
                }
            }
        }


        function filter(articles) {
            console.log(articles);
            //             if (!(keywordsBlackList.length || authorBlackList.length)) return;
            //             articles.each(function () {
            //                 const info = $(this);
            //                 const author = info.find('.username').text();
            //                 const title = info.find('.title').text();
            //                 if (authorBlackList.includes(author) || testTitle(title)) {
            //                     $(this).hide();
            //                 }
            //             });
        }
    }

    function createNodeListener(node, config, mutationCallback) {
        console.log('createNodeListner running');
        console.log(node);
        const observer = new MutationObserver(mutationCallback);
        observer.observe(node, config);
        return observer;
    }

    // 切换回经典版
    function switchToClassicStyle() {
       var back_old_link =document.getElementsByClassName("back_old_link");

       if (back_old_link.length) {
           back_old_link[0].click();
       }
    }

})();