您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
(从“烂虎扑屏蔽器”修改而来。)根据屏蔽标题和作者的关键词
当前为
// ==UserScript== // @name 彪扑 // @namespace https://greasyfork.org/gmail // @version 0.3.2 // @description (从“烂虎扑屏蔽器”修改而来。)根据屏蔽标题和作者的关键词 // @author biopsy // @license Apache Licence 2.0 // @match https://bbs.hupu.com/* // @icon https://w1.hoopchina.com.cn/images/pc/old/favicon.ico // @grant unSafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_log // @grant GM_notification // @grant GM_listValues // @grant GM_deleteValue // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js // ==/UserScript== (function () { 'use strict'; const Keys = {blacklist: "banKeyword", tour: "firstTime"}; function appendAssets() { const $head = $("head"); $head.append($(`<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">`)); $head.append($(`<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">`)); $head.append($(`<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>`)); } function appendElements() { // 添加右下角fab const $body = $("body"); $body.append($(`<div class="fixed-action-btn"> <a id="fab" class="btn-floating btn-large white"> <i class="red-text large material-icons">lightbulb_outline</i> </a> <ul> <li id="fab-first"><a class="btn-floating white tooltip" data-tooltip="调试"><i class="red-text material-icons">mode_edit</i></a></li> <li id='showBanList'><a class="btn-floating white tooltip" data-tooltip="屏蔽词"><i class="red-text material-icons">reorder</i></a></li> </ul> </div> `)); // 添加屏蔽词的chips $body.append($(`<div id="keywordList" class="card-panel teal lighten-1" style="background:grey;display:none; z-index:999;text-align:center;width: 66vw;height: 20vh;position: fixed;inset:0;margin: auto;"> <div class="white-text">语法: %A% 开头屏蔽作者昵称, %I%开头屏蔽作者ID</div> <div class="chips chips-placeholder chips-initial"/> </div>`)); // 添加个click事件,用于判断是否点击在chips组件之外 $('#container').click(() => $('#keywordList').fadeOut(500)); // 初始化 FAB M.FloatingActionButton.init(document.querySelectorAll('.fixed-action-btn'), {direction: 'left'}); // 初始化 tooltip M.Tooltip.init(document.querySelectorAll('.tooltip'), { enterDelay: 200, exitDelay: 0, inDuration: 200, outDuration: 200, position: 'top', transitionMovement: 10 }); } // 添加新用户引导 function addTour(count) { $('body').append($(`<div class="tap-target" data-target="fab"> <div class="tap-target-content"> <h5 style="color:white">自定义设置</h5><br/> <p style="color:white">在这里进行自定义配置</p><br/> <p style="color:white">此新用户引导只显示3次,这是第` + count + `次</p> </div> </div>`)) // FeatureDiscovery初始化 //$('.tap-target').tapTarget() let tapTargetElems = document.querySelectorAll('.tap-target') let tapTargetOptions = { open() { console.log('open') }, close() { console.log('close') } } M.TapTarget.init(tapTargetElems, tapTargetOptions) $('.tap-target').tapTarget('open') } // 显示屏蔽关键字列表(设置过多关键字会导致显示有点不和谐,待修复) function showBanKeyword() { // 挂载需要填入数据并设置可见性为true if ($('#keywordList').length > 0) { let elems = document.querySelectorAll('.chips') const words = GM_getValue(Keys.blacklist) const data = words.map(tag => ({tag})); let options = { data, placeholder: '添加一个屏蔽词', secondaryPlaceholder: '继续添加', onChipAdd: saveChipsData, onChipDelete: saveChipsData, } M.Chips.init(elems, options) alterChipsCardSize(data.length) } } // 根据chips数量来改变该card-panel的大小 function alterChipsCardSize(length) { let height = ((length / 4 & 0) + 1) * 32 + 120; $('#keywordList').css({'display': 'inline', 'height': height + 'px'}) } // 用于chips触发“添加”和“删除”事件后保存数据 function saveChipsData() { let data = M.Chips.getInstance($('.chips')).chipsData let banKeyword = [] data.forEach(function (e) { let keyword = e.tag banKeyword.push(keyword) }) GM_log(banKeyword) alterChipsCardSize(banKeyword.length) // 将数据存储起来 GM_setValue(Keys.blacklist, banKeyword) } //region filter /** * 语法: %A% %I% * @param {string}str * @return {(function(text:string): boolean)} */ function createMatcher(str) { function createIndexMatcher(key) { return (text) => text.indexOf(key) > -1; } function createRegMatcher(key) { const pattern = new RegExp(key); return (text) => pattern.test(text); } if (str.startsWith('/') && s.endsWith('/')) { return createRegMatcher(str.substring(1, str.length - 1)); } else { let fuzzy = false; if (str.indexOf('*') > -1) { fuzzy = true; str = str.replaceAll('*', '.*'); } if (str.indexOf('?') > -1) { fuzzy = true; str = str.replaceAll('?', '.?'); } return fuzzy ? createRegMatcher(str) : createIndexMatcher(str); } } /** * * @param {string[]} arr * @return {function(text:string): boolean} */ function createFluxMatcher(arr) { const matchers = arr.map(x => createMatcher(x.trim())); return function (text) { if (!text) return false; for (let i = 0; i < matchers.length; i++) { if (matchers[i](text)) { return true; } } return false; } } /** * @param {string[]} words * @return {{filterAuthor: boolean, author({id: string, name: string}): boolean, title(string): boolean}} */ function createFilter(words = []) { const titles = [], ids = [], names = []; for (let i = 0; i < words.length; i++) { const s = words[i]; if (s.length > 3) { const codes = [0, 1, 2].map(i => s.charCodeAt(i)); if (codes[0] === 37 && codes[2] === 37) { const c = codes[1]; if (c === 65 || c === 97) { // A names.push(s.substring(3)); } else if (c === 73 || c === 105) { //I ids.push(s.substring(3)); } else { titles.push(s.substring(3)); } } else { titles.push(s); } } else { titles.push(s); } } const titleMatcher = createFluxMatcher(titles); const idMatcher = createFluxMatcher(ids); const nameMatcher = createFluxMatcher(names); return { filterAuthor: ids.length > 0 || names.length > 0, title(text) { return titleMatcher(text); }, author({id, name}) { if (idMatcher(id)) return true; return nameMatcher(name); } } } function hidePostList(filter) { const articles = document.querySelectorAll('.bbs-sl-web-post li'); function shouldHide(elem) { if (filter.filterAuthor) { const el = elem.querySelector('.post-auth a'); const name = el.innerText; const id = el.getAttribute('href').split('/').at(-1); if (filter.author({id, name})) { console.info('hide author:', name, id); return true; } } const title = elem.querySelector('.post-title').innerText; if (filter.title(title)) { console.info('hide title:', title); return true; } return false; } for (let i = 0; i < articles.length; i++) { const foo = articles[i]; if (shouldHide(foo)) { $(foo).css({'background-color': '#81c784', 'color': 'grey'}).fadeOut(500); } } } function hideAd() { // 屏蔽虎扑游戏 $('.game-center-sidebar').remove() $('.game-center-entrance-container-title').remove() $('#game-center-entrance-container').remove() const $hotGame = $(':contains("热门游戏-即点即玩")'); const el = $hotGame[$hotGame.length - 2] if (el) el.innerHTML = ''; } //endregion appendAssets(); appendElements(); $(document).ready(function () { $('#showBanList').click(() => showBanKeyword()); // 调试 $('#fab-first').click(() => { const arr = GM_getValue(Keys.blacklist); console.info('黑名单', arr) const filter = createFilter(); console.info('filter author', filter.filterAuthor) console.info(filter) console.info('author id', filter.author({id: '1234567', name: 'foobar'})) console.info('author name', filter.author({id: 'gg', name: '彭嘎'})) console.info('title contains', filter.title('战绩六芒星')) console.info('title *', filter.title('一起迎着上')) window.filter = filter; }); // hideAd(); const filter = createFilter(GM_getValue(Keys.blacklist)); hidePostList(filter); }) })();