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.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalaçã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);
    }

})()