您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Blurs the covers of NSFW novels on Masiro.
当前为
// ==UserScript== // @name Masiro: Blurs NSFW Covers // @name:zh-TW 真白萌:模糊 R17 封面 // @description Blurs the covers of NSFW novels on Masiro. // @description:zh-TW 模糊真白萌 R17 小說的封面。 // @icon https://icons.duckduckgo.com/ip3/masiro.me.ico // @author Jason Kwok // @namespace https://jasonhk.dev/ // @version 1.2.3 // @license MIT // @match https://masiro.me/admin // @match https://masiro.me/admin/ // @match https://masiro.me/admin/novels // @match https://masiro.me/admin/novelIndex // @run-at document-idle // @grant GM.getValue // @grant GM.setValue // @grant GM.addStyle // @require https://update.greasyfork.icu/scripts/482311/1296481/queue.js // @supportURL http://greasyfork.icu/scripts/471783/feedback // ==/UserScript== GM.addStyle(` .updateCards > a.nsfw .updateImg, .layui-card.nsfw .n-img { filter: blur(7.5px); transition: 0.3s; } .updateCards > a.nsfw:hover .updateImg, .updateCards > a.nsfw:focus-within .updateImg, .layui-card.nsfw:hover .n-img, .layui-card.nsfw:focus-within .n-img { filter: blur(0px); } `); const pathname = location.pathname; if ((pathname === "/admin") || (pathname === "/admin/")) { const queue = new Queue({ autostart: true, concurrency: 4 }); const observer = new MutationObserver((records) => { for (const record of records) { if (record.target.classList.contains("updateCards")) { for (const node of record.addedNodes) { queue.push(async () => { if (await isNsfw(node.href)) { node.classList.add("nsfw"); } }); } } } }); observer.observe(document.querySelector(".fl"), { subtree: true, childList: true }); async function isNsfw(url) { const novelId = new URL(url).searchParams.get("novel_id"); { const isNsfw = await GM.getValue(novelId); if (typeof isNsfw === "boolean") { return isNsfw; } } try { const response = await fetch(url); if (response.status === 200) { const html = await response.text(); const parser = new DOMParser(); const page = parser.parseFromString(html, "text/html"); const isNsfw = Array.prototype.map.call(page.querySelectorAll(".tags .label"), (element) => element.innerText) .includes("R17"); GM.setValue(novelId, isNsfw); return isNsfw; } else if (response.status === 429) { const resetTime = Number.parseInt(response.headers.get("x-ratelimit-reset")); return new Promise((reslove) => { setTimeout(() => reslove(isNsfw(url)), (resetTime - Math.ceil(Date.now() / 1000) + 10) * 1000); }); } } catch (e) { console.error(e); } return false; } } else { const observer = new MutationObserver((records) => { for (const record of records) { for (const node of record.addedNodes) { if ((node instanceof HTMLElement) && node.classList.contains("layui-card")) { const isNsfw = Array.prototype.map.call(node.querySelectorAll(".tags > .tag"), (element) => element.innerText).includes("R17"); if (isNsfw) { node.classList.add("nsfw"); } const url = new URL(node.querySelector(".glass + a").href); GM.setValue(url.searchParams.get("novel_id"), isNsfw); } } } }); observer.observe(document.querySelector(".n-leg"), { childList: true }); }