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.

目前為 2021-03-08 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

/*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.1
// @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 = location.href;
let artworkUrl = /^(http|https):\/\/(www)?\.pixiv\.net\/artworks\/.*/;

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

let allIllustsSet = new Set();
let sensitiveIllustsSet = 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';

switch(isEnabled){
      case true:
         switchButton.innerHTML = ONText;
         break;
      case false:
         switchButton.innerHTML = OFFText;
         break;
}

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

document.body.appendChild(switchButton);

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

switchButton.addEventListener('click', function(){
   switch(isEnabled){
      case true:
         isEnabled = false;
         switchButton.innerHTML = OFFText;
         if(artworkUrl.test(href)){ location.reload(); }
         break;
      case false:
         isEnabled = true;
         switchButton.innerHTML = ONText;
         enableObservation();
         break;
   }
   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();
      return;
   }

   if(artworkUrl.test(href)){
      enableObservation();
   }
})

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

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

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

///関数定義

function enableObservation(){
   if(!isEnabled || !artworkUrl.test(href)){ return; }

   recommendSection = updateRecommendSection(recommendSection);
   if(recommendSection){
      recommendObserver.observe(recommendSection, {attributes: true, subtree: true});
   }
}

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

function deleteNotSensitiveIllust(recom){
   if(!recom){ return; }

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

})()