Sleazy Fork is available in English.

Script to switch recommended works on pixiv to show only R-18 works

allows you to display only R-18 works in the recommended works at the bottom of the artwork page.

Versão de: 01/04/2021. Veja: a última versão.

/*jshint esversion: 6 */

// ==UserScript==
// @name        Script to switch recommended works on pixiv to show only R-18 works
// @name:ja           pixivの関連作品をR-18オンリーと切り替えるスクリプト
// @name:zh-CN     将pixiv上的推荐作品切换为只显示R-18的Script
// @description allows you to display only R-18 works in the recommended works at the bottom of the artwork page.
// @description:ja pixivの作品画面の下部に表示される関連作品を、R-18作品に絞って表示することができます。
// @description:zh-cn 它可以让您在作品页面底部的推荐作品中只显示R-18作品。
// @version        0.5.3
// @author         Qappendix
// @license        GPL v3; https://www.gnu.org/copyleft/gpl.html
// @match          *://www.pixiv.net/*
// @grant          GM_setValue
// @grant          GM_getValue
// @namespace https://greasyfork.org/users/724570
// ==/UserScript==

(function() {
    //変数初期化

    let recommendSection = null;
    let href;
    let artworkUrl = /^(http|https):\/\/(www)?\.pixiv\.net\/artworks\/.*/;

    let isEnabled = GM_getValue('isEnabled', true);
    let isArtworkURL = false;

    let allIllustsSet = new Set();
    let sensitiveIllustsSet = new Set();
    let notSensitiveIllustsSet = new Set();

    ///ボタン要素追加

    let switchButton = document.createElement('button');
    let switchButtonStyle = 'position: fixed; bottom: 10px; right: 10px; padding: 6px 40px;';
    let ONText = 'R-18 only: ON';
    let OFFText = 'R-18 only: OFF';

    isEnabled ? switchButton.innerHTML = ONText : switchButton.innerHTML = OFFText;

    switchButton.id = 'switch_button';
    switchButton.setAttribute('Style', switchButtonStyle)

    document.body.appendChild(switchButton);

    //ボタンクリック時イベント定義

    switchButton.addEventListener('click', function(){
        isEnabled =! isEnabled;

        if(isEnabled){
            switchButton.innerHTML = ONText;
            enableObserver();
            toggleDisplayIllusts();
        }else{
            switchButton.innerHTML = OFFText;
            toggleDisplayIllusts();
        }
        GM_setValue('isEnabled',isEnabled);
    });

    ///MutationObserver定義

    //ページ遷移検出、初期化
    let documentObserver = new MutationObserver( function(){
        if(href !== location.href){
            href = location.href;
            recommendSection = null;
            recommendObserver.disconnect();
            allIllustsSet.clear();
            sensitiveIllustsSet.clear();
            artworkUrl.test(href) ? isArtworkURL = true : isArtworkURL = false;
        }
        if(isArtworkURL){
            if(!document.getElementById("recommend_section")){
                updateRecommendSection();
                recommendSection.id = "recommend_section";
                enableObserver();
            }
        }
    })

    let recommendObserver = new MutationObserver( function(){
        updateIllustsSet(recommendSection);
        toggleDisplayIllusts();
    })

    //文書全体の変更を監視

    documentObserver.observe(document, {attributes: true, subtree: true});

    ///関数定義
    function enableObserver(){
        recommendObserver.observe(recommendSection, {attributes: true, subtree: true});
    }

    function updateRecommendSection(){
        for(let section of document.body.getElementsByTagName("section")){
            for(let div of section.getElementsByTagName("div")){
                if(div.textContent == "関連作品" || div.textContent == "おすすめ作品"){
                    recommendSection = section;
                }
            }
        }
    }

    function updateIllustsSet(recom){
        Array.prototype.forEach.call(recom.getElementsByTagName("li"), function(li){
            allIllustsSet.add(li);
            if(li.textContent.indexOf("R-18")!=-1){
                sensitiveIllustsSet.add(li);
            }
        })
        for(let work of allIllustsSet){
            if(!sensitiveIllustsSet.has(work)){
                notSensitiveIllustsSet.add(work);
            }
        }
    }


    function toggleDisplayIllusts(){
        if(sensitiveIllustsSet.size!=0){
            if(isEnabled){
                for(let work of notSensitiveIllustsSet){
                    work.style.display="none";
                }
            }else{
                for(let work of notSensitiveIllustsSet){
                    work.style.display="block";
                }
            }
        }
    }

    function non_R18_Message(){
        let messageText = "Viewing work is not R-18 work. R-18 only mode is off.";
        let messageElement = document.createElement('div');
        let messageStyle = 'position: fixed; top: 100px; right: 100px; padding: 6px 40px;';

        messageElement.id = 'non_R18_Message';
        messageElement.setAttribute('Style', messageStyle)
        messageElement.innerHTML = messageText;
        document.body.appendChild(messageElement);
    }

})()