colgThemeFilter

使用正则表达式根据用户设置的关键词过滤主题

目前為 2022-03-17 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         colgThemeFilter
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  使用正则表达式根据用户设置的关键词过滤主题
// @author       Genmaicha
// @license      MIT
// @match        https://bbs.colg.cn/forum*
// @icon         https://static.colg.cn/image/mobile/images/app-icon.png
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const searchUrl = "https://bbs.colg.cn/search.php?mod=forum_list&";

    var platformType;
    const platform = {
        "电脑版": {
            "userMenu": "#um",
            "threadList": "#threadlisttableid",
            "titleBlock": "tbody",
            "titleTag": ".s.xst",
            "newTitleBlock": ".newthread"
        },
        "触屏版": {
            "userMenu": ".footer",
            "threadList": ".threadlist",
            "titleBlock": "li",
            "titleTag": "a",
            "newTitleBlock": ""
        },
        "标准版": {
            "userMenu": ".pd2",
            "threadList": ".bm",
            "titleBlock": ".bm_c",
            "titleTag": "a",
            "newTitleBlock": ""
        }
    }
    const titleStyle = [{
        "id": "prefer",
        "head": "偏好主题",
        "styles": {
            "高亮": "background: #2B65B7;color: #fff;",
            "红色": "font-weight: bold;color: #EE1B2E;",
            "自定义": ""
        }
    }, {
        "id": "disgust",
        "head": "厌恶主题",
        "styles": {
            "删除线": "text-decoration-line: line-through;",
            "隐藏": "display: none;",
            "自定义": ""
        }
    }]

    Main();

    function Main() {
        checkPlatForm();
        createSettingAnchor();
        updateAllTheme();
        observeNewTheme();
    }

    function checkPlatForm() {
        for (let key in platform) {
            let queryStr = platform[key];
            let userMenu = document.querySelector(queryStr["userMenu"]);
            if (userMenu) {
                platformType = key;
                continue;
            }
        }
        if (!platformType) {
            alert("未识别平台类型,无法获取页面信息");
            return;
        }
        window.addEventListener('load', function() {
            if (platformType == "触屏版") {
                try {
                    // 简化界面
                    let callUpContainer = document.getElementById("callUpContainer");
                    callUpContainer.style.display = "none";
                    // 搜索选项
                    let logo = document.querySelector('.logo-icon');
                    logo.outerHTML = `<select>
                    <option value=3>全文</option>
                    <option value=4>标题</option>
                    <option value=2>用户</option>
                    </select>`
                    // 搜索框
                    let serchContainer = document.querySelector('.search-container');
                    serchContainer.removeAttribute('onclick');
                    serchContainer.style = "margin-left: 15px;";
                    let marquee = serchContainer.querySelector('.marquee');
                    marquee.style.display = 'none';
                    let input = serchContainer.querySelector('input');
                    input.type = "search";
                    input.addEventListener('search',onSearchButtonClick);
                } catch (e) {
                    window.console.log(e);
                }
            }
        })
    }

    async function onSearchButtonClick(e){
        let select = e.target.parentElement.previousElementSibling;
        let type = select.options[select.selectedIndex].value;
        let keyword = e.target.value;
        let url = searchUrl + `type=${type}&keyword=${keyword}`;
        window.location.href = url;
    }

    function createSettingAnchor() {
        let anchor = document.createElement('a');
        anchor.href = "javascript:void(0);";
        anchor.textContent = "主题过滤器";
        anchor.addEventListener('click', callDialog);
        let userMenu = document.querySelector((platform[platformType])["userMenu"]);
        let p = userMenu.querySelector('p');
        if (!p) {
            userMenu.appendChild(anchor);
            return;
        }
        p.appendChild(anchor);
    }

    function callDialog() {
        let userMenu = document.querySelector((platform[platformType])["userMenu"]);
        let dialog = userMenu.querySelector('dialog');
        if (!dialog) {
            let closeButton = document.createElement('button');
            closeButton.textContent = "x";
            closeButton.style = "position:absolute;top:0;right:0;border:none;";
            closeButton.addEventListener('click', closeDialog);
            let form = createSettingForm();
            dialog = document.createElement('dialog');
            dialog.appendChild(closeButton);
            dialog.appendChild(form);
            userMenu.appendChild(dialog);
        }
        if (typeof dialog.showModal != 'function') {
            alert("不支持dialog API,请升级你的浏览器");
            return;
        }
        dialog.showModal();
    }

    function createSettingForm() {
        let div = document.createElement('div');
        let setting = !localStorage.setting ? {} : JSON.parse(localStorage.setting);
        for (let item of titleStyle) {
            let ul = document.createElement('ul');
            ul.id = item.id;
            let headli = document.createElement('li');
            headli.innerHTML = item.head;
            ul.appendChild(headli);
            let selectli = document.createElement('li');
            let select = document.createElement('select');
            let subsetting = setting[item.id] || {};
            for (let key in item.styles) {
                let option = document.createElement('option');
                if (subsetting && subsetting.head && subsetting.head == key) {
                    option.setAttribute('selected', "");
                    option.value = subsetting.style;
                } else {
                    option.value = (item.styles)[key];
                }
                option.textContent = key;
                select.appendChild(option);
            }
            select.addEventListener('change', function(e) {
                let input = e.target.nextElementSibling;
                input.value = e.target.options[select.selectedIndex].value;
            });
            let input = document.createElement('input');
            input.size = 35;
            input.style = "margin-left:10px;"
            input.value = select.options[select.selectedIndex].value;
            selectli.appendChild(select);
            selectli.appendChild(input);
            ul.appendChild(selectli);
            let datali = document.createElement('li');
            let keyword = !subsetting ? "" : subsetting["keyword"];
            datali.innerHTML = `关键词</br><textarea rows="5" cols="50" placeholder="任意关键词1|关键词2|关键词3">${keyword}</textarea>`
            ul.appendChild(datali);
            div.appendChild(ul);
        }
        let p = document.createElement('p');
        p.style = "text-align: center;";
        p.appendChild(createButton("保存", onSaveButtonClick));
        p.appendChild(createButton("取消", closeDialog));
        div.appendChild(p);
        return div;
    }

    function createButton(text, event) {
        let button = document.createElement('button');
        button.textContent = text;
        button.style = "margin-right:30px;";
        button.addEventListener('click', event);
        return button;
    }

    function onSaveButtonClick(e) {
        let p = e.target.parentElement;
        let div = p.parentElement;
        let uls = div.querySelectorAll('ul');
        let setting = {};
        for (let i = 0; i < uls.length; i++) {
            let ul = uls[i];
            let select = ul.querySelector('select');
            let input = ul.querySelector('input');
            let textarea = ul.querySelector('textarea');
            setting[ul.id] = {
                "head": select.options[select.selectedIndex].text,
                "style": input.value,
                "keyword": textarea.value
            }
        }
        localStorage.setting = JSON.stringify(setting);
        localStorage.themeRecord = "";
        closeDialog();
        alert("保存成功");
        updateAllTheme();
    }

    function closeDialog() {
        let dialog = document.querySelector('dialog');
        if (!dialog) {
            return;
        }
        dialog.close();
    }

    function updateAllTheme() {
        let threadList = document.querySelector((platform[platformType])["threadList"]);
        if (!threadList) {
            return;
        }
        let anchorParent = threadList.querySelectorAll((platform[platformType])["titleBlock"]);
        updateThemeStyle(anchorParent);
    }

    function observeNewTheme() {
        let threadList = document.querySelector((platform[platformType])["threadList"]);
        if(!threadList){
            return;
        }
        const config = { childList: true };
        const threadListOBS = new MutationObserver(updatePartTheme);
        threadListOBS.observe(threadList, config);
    }

    function updatePartTheme() {
        let threadList = document.querySelector((platform[platformType])["threadList"]);
        let anchorParent = threadList.querySelectorAll((platform[platformType])["newTitleBlock"]);
        if(!anchorParent){
            return;
        }
        updateThemeStyle(anchorParent);
    }

    function updateThemeStyle(anchorParent) {
        if (!localStorage.setting) {
            alert("请点击主题过滤器设置关键词");
            return;
        }
        let setting = JSON.parse(localStorage.setting);
        let themeRecord = !localStorage.themeRecord ? {} : JSON.parse(localStorage.themeRecord);
        for (let parent of anchorParent) {
            let anchor = parent.querySelector((platform[platformType])["titleTag"]);
            if (!anchor) {
                continue;
            }
            let id = anchor.href.match("\\d{2,}").toString();
            let title = anchor.textContent;
            if (themeRecord[id]) {
                anchor.style = themeRecord[id];
            } else {
                for (var key in setting) {
                    let subsetting = setting[key];
                    let keyword = subsetting["keyword"];
                    if (title.search(keyword) != -1) {
                        let style = subsetting["style"];
                        anchor.style = style;
                        themeRecord[id] = style;
                    }
                }
            }
            if (anchor.style.display == 'none') {
                block.style.display = 'none';
            }
        }
        localStorage.themeRecord = JSON.stringify(themeRecord);
    }

})();