Greasy Fork is available in English.
隐藏NSFW条目
当前为
// ==UserScript==
// @name Bangumi 隐藏NSFW条目
// @version 3.1
// @description 隐藏NSFW条目
// @author 墨云
// @match https://bangumi.tv/*
// @match https://chii.in/*
// @match https://bgm.tv/*
// @grant none
// @namespace http://greasyfork.icu/users/1354622
// ==/UserScript==
(function() {
'use strict';
if (window.location.pathname.startsWith('/subject/')) {
return;
}
const SETTING_KEY = 'bangumi_hide_nsfw_mode';
const CACHE_EXPIRY = 7 * 24 * 60 * 60 * 1000;
async function isSubjectChecked(subjectId) {
const cacheKey = `nsfw_cache_${subjectId}`;
const cachedData = localStorage.getItem(cacheKey);
if (cachedData) {
try {
const data = JSON.parse(cachedData);
if (Date.now() < data.timestamp + CACHE_EXPIRY) {
return data.value;
}
} catch (e) {
localStorage.removeItem(cacheKey);
}
}
try {
const response = await fetch(`/subject/${subjectId}/edit_detail`);
const text = await response.text();
const isChecked = text.includes('checked="checked"');
const dataToCache = {
value: isChecked,
timestamp: Date.now()
};
localStorage.setItem(cacheKey, JSON.stringify(dataToCache));
return isChecked;
} catch (error) {
console.error('Failed to fetch subject detail:', error);
const dataToCache = {
value: false,
timestamp: Date.now()
};
localStorage.setItem(cacheKey, JSON.stringify(dataToCache));
return false;
}
}
function getSubjectIdFromLink(link) {
const url = link.href;
if (url.startsWith('https://bangumi.tv/subject/')) {
return url.split('/')[4];
} else if (url.startsWith('/subject/')) {
return url.split('/')[2];
}
return null;
}
async function applyMode(mode) {
const listItems = document.querySelectorAll('li > a[href^="/subject/"], li.tml_item a[href^="https://bangumi.tv/subject/"], #user_home li a[href^="https://bangumi.tv/subject/"], #columnSubjectBrowserA .mainItem a[href^="https://bangumi.tv/subject/"], #columnSubjectBrowserA .mainItem a[href^="/subject/"]');
const promises = [];
for (const item of listItems) {
const subjectId = getSubjectIdFromLink(item);
if (subjectId) {
promises.push(isSubjectChecked(subjectId).then(isChecked => {
if (isChecked) {
let containerToHide;
if (item.closest('#columnSubjectBrowserA')) {
containerToHide = item.closest('.mainItem');
} else {
containerToHide = item.closest('li');
}
if (containerToHide) {
containerToHide.style.display = (mode === 'hide') ? 'none' : '';
}
}
}));
}
}
await Promise.all(promises);
}
function addNSFWSetting() {
chiiLib.ukagaka.addGeneralConfig({
title: 'NSFW',
name: 'nsfwMode',
type: 'radio',
defaultValue: 'off',
getCurrentValue: function() { return $.cookie(SETTING_KEY) || 'off'; },
onChange: function(value) {
$.cookie(SETTING_KEY, value, {expires: 30, path: '/'});
applyMode(value);
},
options: [
{ value: 'off', label: '关闭' },
{ value: 'hide', label: '隐藏' }
]
});
}
async function init() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', addNSFWSetting);
} else {
addNSFWSetting();
}
const currentMode = $.cookie(SETTING_KEY) || 'off';
await applyMode(currentMode);
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1 && node.querySelector('a[href^="/subject/"], a[href^="https://bangumi.tv/subject/"]')) {
console.log('检测到新条目加载,正在应用设置...');
applyMode($.cookie(SETTING_KEY) || 'off');
}
});
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
init();
})();