Greasy Fork

来自缓存

Greasy Fork is available in English.

Tong Li Online: Blurs R-rated Covers

Blurs the covers of R-rated novels on Tong Li Online.

当前为 2024-02-12 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name               Tong Li Online: Blurs R-rated Covers
// @name:zh-TW         東立漫遊網:模糊限制級封面
// @description        Blurs the covers of R-rated novels on Tong Li Online.
// @description:zh-TW  模糊東立漫遊網限制級書本的封面。
// @icon               https://icons.duckduckgo.com/ip3/www.tongli.com.tw.ico
// @author             Jason Kwok
// @namespace          https://jasonhk.dev/
// @version            1.2.0
// @license            MIT
// @match              https://www.tongli.com.tw/
// @match              https://www.tongli.com.tw/index.aspx
// @match              https://www.tongli.com.tw/search3.aspx
// @match              https://www.tongli.com.tw/Search3.aspx
// @match              https://www.tongli.com.tw/BooksList.aspx
// @match              https://www.tongli.com.tw/BooksList.aspx?*
// @match              https://www.tongli.com.tw/GbooksList.aspx
// @match              https://www.tongli.com.tw/GbooksList.aspx?*
// @match              https://www.tongli.com.tw/webpagebooks.aspx
// @match              https://www.tongli.com.tw/webpagebooks.aspx?*
// @match              https://www.tongli.com.tw/WebPageBooks.aspx
// @match              https://www.tongli.com.tw/WebPageBooks.aspx?*
// @match              https://www.tongli.com.tw/ThemeBL.aspx
// @match              https://www.tongli.com.tw/ThemeBLBooks.aspx
// @match              https://www.tongli.com.tw/ThemeBLBooks.aspx?*
// @match              https://www.tongli.com.tw/ThemeBeautiful.aspx
// @match              https://www.tongli.com.tw/ThemeBeautiful.aspx?*
// @match              https://www.tongli.com.tw/ThemeGL.aspx
// @match              https://www.tongli.com.tw/ThemeGL.aspx?*
// @match              https://www.tongli.com.tw/NovelIndex/
// @match              https://www.tongli.com.tw/NovelDetail.aspx
// @match              https://www.tongli.com.tw/NovelDetail.aspx?*
// @run-at             document-end
// @grant              none
// @require            https://update.greasyfork.icu/scripts/483122/1304475/style-shims.js
// @require            https://update.greasyfork.icu/scripts/482311/1297431/queue.js
// @supportURL         http://greasyfork.icu/scripts/482312/feedback
// ==/UserScript==

GM.addStyle(`
    .b_package.nsfw img, .owl-item.nsfw > .item img, .comicBox li.nsfw img, .sdBook :is(.hot, .tabbook).nsfw input
    {
        filter: blur(7.5px);
        transition: 0.3s;
    }

    .b_package.nsfw:hover img, .b_package.nsfw:focus-within img,
    .owl-item.nsfw > .item:hover img, .owl-item.nsfw > .item:focus-within img,
    .comicBox li.nsfw:hover img, .comicBox li.nsfw:focus-within img,
    .sdBook :is(.hot, .tabbook).nsfw:hover input, .sdBook :is(.hot, .tabbook).nsfw:focus-within input
    {
        filter: blur(0px);
    }
`);

async function isNsfw(url, { signal } = {})
{
    try
    {
        const response = await fetch(url, { signal });
        if (response.status === 200)
        {
            const html = await response.text();
            const parser = new DOMParser();
            const page = parser.parseFromString(html, "text/html");

            if (page.getElementById("ContentPlaceHolder1_GradeTxt")?.innerText === "限制級") { return true; }
        }
    }
    catch (e)
    {
        if (typeof e === "string")
        {
            console.debug(e);
        }
        else if ((e instanceof DOMException) && (e.name === "AbortError"))
        {
            console.debug(signal.reason);
        }
        else
        {
            console.error(e);
        }
    }

    return false;
}

const queue = new Queue({ autostart: true, concurrency: 20 });

const pathname = location.pathname.toLowerCase();
if ((pathname === "/bookslst_srh.aspx") || (pathname === "/gbookslist.aspx"))
{
    const serieses = document.querySelectorAll(".b_package");
    for (const series of serieses)
    {
        queue.push(async () =>
        {
            try
            {
                const response = await fetch(series.querySelector("a").href);
                if (response.status === 200)
                {
                    const html = await response.text();
                    const parser = new DOMParser();
                    const page = parser.parseFromString(html, "text/html");

                    const controller = new AbortController();
                    const signal = controller.signal;

                    const products = page.querySelectorAll(".b_package");
                    for (const product of products)
                    {
                        queue.push(async () =>
                        {
                            if (await isNsfw(product.querySelector("a").href, { signal }))
                            {
                                controller.abort(`Skipping other checks for the series “${series.querySelector(".pk_txt > em").innerText}” since a R-rated book in it has already been found.`);
                                series.classList.add("nsfw");
                            }
                        });
                    }
                }
            }
            catch (e)
            {
                console.error(e);
            }
        });
    }
}
else
{
    const products = document.querySelectorAll(".b_package, .owl-item, .comicBox li");
    for (const product of products)
    {
        queue.push(async () =>
        {
            if (await isNsfw(product.querySelector("a").href))
            {
                product.classList.add("nsfw");
            }
        });
    }

    if (pathname === "/search3.aspx")
    {
        const sandbox = document.createElement("iframe");
        sandbox.style = "display: none;"
        document.body.appendChild(sandbox);

        sandbox.contentWindow.WebForm_PostBackOptions = window.WebForm_PostBackOptions;
        sandbox.contentWindow.WebForm_DoPostBackWithOptions = (options) => (new URL(options.actionUrl, location).href);

        const products = document.querySelectorAll(".sdBook :is(.hot, .tabbook)");
        for (const product of products)
        {
            const url = sandbox.contentWindow.eval(product.querySelector("input").getAttribute("onclick"));

            queue.push(async () =>
            {
                if (await isNsfw(url))
                {
                    product.classList.add("nsfw");
                }
            });
        }

        sandbox.remove();
    }
}