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.

Versione datata 23/04/2021. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

/*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.5
// @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; z-index: 101;';
    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);

    //非R-18作品閲覧時メッセージ追加
    let messageText = "Viewing work is not R-18 work. R-18 only mode is off.";
    let messageElement = document.createElement('div');
    let messageStyle = 'display: none; width: calc(100vw - (100vw - 100%)); height: 2vh; position: -webkit-sticky; position: sticky; top: 98vh; background-color: gray; z-index: 100;';

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

    //ボタンクリック時イベント定義
    switchButton.addEventListener('click', function(){
        isEnabled =! isEnabled;

        if(isEnabled){
            switchButton.innerHTML = ONText;
            recommendObserver.observe(recommendSection, {attributes: true, subtree: true});
            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){
            updateRecommendSection();
            recommendObserver.observe(recommendSection, {attributes: true, subtree: true});
        }
        toggleNonR18Message();
    })

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

    //文書全体の変更を監視
    documentObserver.observe(document, {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 toggleNonR18Message(){
        var non_R18_Message = document.getElementById("non_R18_Message");
        if(sensitiveIllustsSet.size!=0 || !isArtworkURL){
            non_R18_Message.style.display="none";
        }else if(allIllustsSet.size!=0 && isArtworkURL && isEnabled){
            non_R18_Message.style.display="block";
        }
    }

})()