您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Sleazy Fork is available in English.
Block specified user in artists page and posts page.
当前为
// ==UserScript== // @name Kemono.Party - User Filter // @description Block specified user in artists page and posts page. // @version 1.11 // @match https://*.kemono.su/posts* // @match https://*.kemono.su/artists* // @match https://*.kemono.su/*/user/* // @exclude /\/post\// // @namespace none // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== /* jshint esversion: 6 */ let blacklists = GM_getValue('blacklists', []); let filter_enabled = GM_getValue('filter_enabled', true); let is_user_page = location.pathname.indexOf('/user/') >= 0; let is_posts_page = location.pathname.indexOf('/posts') == 0; let is_artists_page = location.pathname.indexOf('/artists') == 0; addStyle(); addFilterButton(); addBlockButton(); function addFilterButton() { let ptop = document.querySelector('#paginator-top'); if (is_posts_page) { let menu = ptop.querySelector('menu'); if (menu) addFilterButtonTo(menu); } else if (is_artists_page) { new MutationObserver(() => { let menu = ptop.querySelector('menu'); if (menu) addFilterButtonTo(menu); }).observe(ptop, {childList: true, subtree: false}); } } function addFilterButtonTo(menu) { let btn_switch = document.createElement('a'); btn_switch.classList.add('filter-switch'); btn_switch.innerHTML = '<b>Filter</b>'; if (filter_enabled) menu.closest('section').classList.add('filter-enabled'); else btn_switch.classList.add('pagination-button-disabled'); menu.insertBefore(btn_switch, menu.firstChild); btn_switch.onclick = () => { filter_enabled = !filter_enabled; menu.closest('section').classList.toggle('filter-enabled'); btn_switch.classList.toggle('pagination-button-disabled'); GM_setValue('filter_enabled', filter_enabled); }; } function addBlockButton() { if (is_posts_page) document.querySelectorAll('article.post-card').forEach(card => addBlockButtonTo(card, true)); let items = document.querySelector('.card-list__items'); if (items) { new MutationObserver(mutations => mutations.forEach(mutation => mutation.addedNodes.forEach(card => { if (card.classList.contains('post-card') || card.classList.contains('user-card')) addBlockButtonTo(card); }))).observe(items, {childList: true, subtree: false}); } if (is_user_page) addBlockButtonToUserPage(); } function addBlockButtonTo(card) { let service = card.dataset.service || card.href.split('/')[3]; let user = card.dataset.user || card.href.split('/').pop(); let is_blocked = blacklists.indexOf(service + '_' + user) >= 0; if (is_blocked) card.dataset.blocked = true; let btn_block = document.createElement('label'); btn_block.classList.add('btn-block'); btn_block.innerHTML = `<b></b>`; (card.querySelector('footer') || card).appendChild(btn_block); btn_block.onclick = e => { e.preventDefault(); btn_block.closest('a').blur(); blockUser(service, user, card.dataset.blocked, is_artists_page && card); }; if (is_posts_page) { btn_block.onmouseover = () => hintUser(service, user, card.dataset.blocked, true); btn_block.onmouseout = () => hintUser(service, user); } } function addBlockButtonToUserPage() { let [service, user] = location.pathname.slice(1).split('/user/'); let is_blocked = blacklists.indexOf(service + '_' + user) >= 0; let header_actions = document.querySelector('.user-header__actions'); let btn_block = document.createElement('a'); btn_block.classList.add('btn-block-user'); if (is_blocked) btn_block.classList.add('blocked'); header_actions.appendChild(btn_block); btn_block.onclick = () => { btn_block.classList.toggle('blocked'); let post_cards = document.querySelectorAll(`article.post-card`); post_cards.forEach(post_card => blockCard(post_card, is_blocked)); blockUser(service, user, is_blocked); is_blocked = !is_blocked; }; } function blockUser(service, user, is_blocked, user_card) { if (user_card) blockCard(user_card, is_blocked); else if (is_posts_page) { let post_cards = document.querySelectorAll(`article.post-card[data-service="${service}"][data-user="${user}"]`); post_cards.forEach(post_card => blockCard(post_card, is_blocked)); } //update and save blacklists let user_id = service + '_' + user; if (is_blocked) { blacklists = blacklists.filter(id => id !== user_id); } else { blacklists.push(user_id); } GM_setValue('blacklists', blacklists); } function blockCard(card, is_blocked) { if (is_blocked) card.removeAttribute('data-blocked'); else card.setAttribute('data-blocked', true); } function hintUser(service, user, is_blocked, onmouseover) { let post_cards = document.querySelectorAll(`article.post-card[data-service="${service}"][data-user="${user}"]`); post_cards.forEach(post_card => { if (onmouseover) { post_card.setAttribute(is_blocked ? 'data-hint-unblock' : 'data-hint-block', true); } else { post_card.removeAttribute('data-hint-block'); post_card.removeAttribute('data-hint-unblock'); } }); } function addStyle() { let css = ` menu > a.filter-switch {color: orange;} .filter-enabled [data-blocked] {display: none;} /* card glow */ .user-card, .post-card > a {transition: box-shadow .25s ease, opacity .25s ease;} .user-card[data-blocked], .post-card[data-blocked] > a {opacity: 0.75; box-shadow: 0 0 4px 2px orangered;} .post-card[data-hint-block] > a {opacity: 1; box-shadow: 0 0 4px 2px orange;} .post-card[data-hint-unblock][data-blocked] > a {opacity: 1; box-shadow: 0 0 4px 2px yellowgreen;} /* block button */ :not([data-blocked]) .btn-block:not(:hover) b {visibility: hidden;} .btn-block {padding: 10px; position: absolute; right: -5px; bottom: -5px;} .btn-block > b {color: white; background-color: orangered; border: 1px solid black; border-radius: 4px; padding: 0 4px;} .btn-block > b::before {content: 'Block User'} [data-blocked] .btn-block > b::before {content: 'Blocked';} [data-blocked] .btn-block:hover > b {background-color: yellowgreen;} [data-blocked] .btn-block:hover > b::before {content: 'Unblock';} /* block button (user page) */ .btn-block-user {color: grey;} .btn-block-user::before {content: 'Block'} .btn-block-user.blocked {color: orangered;} .btn-block-user.blocked::before {content: 'Blocked'} /* UI fix for AutoPagerize */ .autopagerize_page_separator, .autopagerize_page_info {flex: unset; width: 100%;} `; document.head.insertAdjacentHTML('beforeend', `<style>${css}</style>`); }