Greasy Fork

Greasy Fork is available in English.

Novel Ranking Filter [No GM_API Version]

Novel Ranking Filtering Bookmarklet for Mobile Browser

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name           Novel Ranking Filter [No GM_API Version]
// @name:ja        小説ランキングフィルター [GM_APIなし]
// @namespace      http://greasyfork.icu/en/users/1264733
// @version        2024-06-23
// @description    Novel Ranking Filtering Bookmarklet for Mobile Browser
// @description:ja モバイルブラウザ用小説ランキングフィルタリングブックマークレット
// @author         LE37
// @license        MIT
// @include        https://www.alphapolis.co.jp/novel/index*
// @include        https://www.alphapolis.co.jp/novel/ranking/*
// @include        https://kakuyomu.jp/genr*
// @include        https://kakuyomu.jp/pick*
// @include        https://kakuyomu.jp/rank*
// @include        https://kakuyomu.jp/sear*
// @include        https://kakuyomu.jp/rece*
// @include        https://syosetu.org/?mode=rank*
// @include        https://yomou.syosetu.com/rank/*
// @include        https://yomou.syosetu.com/search*
// @exclude        https://www.alphapolis.co.jp/novel/ranking/annual
// @exclude        https://yomou.syosetu.com/rank/top/
// @grant          none
// ==/UserScript==

(()=>{
	/*LS20240623*/
	'use strict';
	// GM key, Nodelist, userLink, userid, tag, alt;
	let gMk,eNo,eUl,sId,sTg,eAt;
	// View mode 
	let V=false;
	// Current list
	let O,A,T;
	// Client type
	const M=navigator.userAgent.includes("Mobile");
	const P=location.pathname;
	switch(location.host){
		case "www.alphapolis.co.jp":
			gMk="A";
			eNo="div.section";
			eUl="div.author>a";
			sId=/detail\/(\d+)$/;
			sTg="li.tag a";
			break;
		case "syosetu.org":
			gMk="H";
			eNo=M?"div.search_box":"div.section3";
			eUl=null;
			sId=/:(.*)/;
			sTg=M?'span[id^="tag_"]':'div.all_keyword:nth-child(9) a';
			eAt=M?"p:nth-child(2)":"div.blo_title_sak";
			break;
		case "kakuyomu.jp":
			gMk="K";
			sId=/users\/(.*)$/;
			if(P.startsWith("/search")){
				eNo=M?'div[class*="Spacer_margin-ml-m__"]':'div[class*="NewBox_borderSize-bb"]';
				eUl=M?'span[class*="workLabelAuthor__"] a':"div.partialGiftWidgetActivityName>a";
				sTg='a[href^="/tags/"]';
			}else if(P.startsWith("/recent_r")){
				eNo="div.recentReviews-item";
				eUl="a.widget-workCard-authorLabel";
				sTg='a[href^="/tags/"]';
			}else{
				eNo="div.widget-work";
				eUl="a.widget-workCard-authorLabel";
				sTg="a[itemprop='keywords']";
			}
			break;
		case "yomou.syosetu.com":
			gMk="N";
			if(P.startsWith("/search")){
				eNo=M?"div.smpnovel_list":"div.searchkekka_box";
				eUl=M?null:"a:nth-child(2)";
				sId=M?/:(.*)/:/\/(\d+)/;
				sTg='a[href*="?word"]';
				eAt="p.author";
			}else{
				eNo="div.p-ranklist-item";
				eUl="div.p-ranklist-item__author a";
				sId=/\/(\d+)/;
				sTg="div.p-ranklist-item__keyword a";
			}
			break;
	}
	//console.log( {gMk, eNo, eUl, sId, sTg, eAt} );
	// Read list
	function URD(){
		const G=JSON.parse(localStorage.getItem(gMk));
		O=G?G:{AL:[],TL:[]};
		A=O.AL;
		T=O.TL;
	}
	// Save list
	function USV(){
		if(JSON.stringify(O)!==localStorage.getItem(gMk)){
			localStorage.setItem(gMk,JSON.stringify(O));
		}
	}
	// Run
	URD();
	FMD();
	CFB();
	// Filtering multiple targets
	function FMD(){
		const no=document.querySelectorAll(eNo);
		for(let i=0;i<no.length;i++){
			let rBk=false;
			let uId;
			// Filtering content contain single id(link) or text
			let eLk=eUl?no[i].querySelector(eUl):no[i].querySelector(eAt);
			if(eLk!==null||(gMk==="N"&&M)){
				if(!eLk){
					// Narou search mobile no author link
					if(gMk==="N"){
						const tca=document.createElement("p");
						tca.classList.add("author");
						tca.style.color="#fe7643";
						const head=no[i].querySelector("div.accordion_head");
						// AD
						if(!head){
							//console.log("===A D===");
							//rBk = true;
							continue;
						}
						tca.textContent=head.textContent.split("\n")[3];
						no[i].querySelector("a.read_button").after(tca);
						eLk=tca;
						uId=eLk.textContent.match(sId)[1];
					}
				}else{
					uId=eUl?eLk.href.match(sId)[1]:eLk.textContent.match(sId)[1];
				}
				//console.log(uId);
				rBk=CHK(eLk,"a",A,uId);
			}
			if(sTg&&!rBk){
				// Filtering content contain multiple tags(text)
				// Tag node
				let tno;
				// Hameln mobile origin tag, custom tag
				let tot,tct;
				if(gMk==="H"&&M){
					tot=no[i].querySelector(".trigger p:nth-child(4)");
					tct=no[i].querySelector(sTg);
					if(!tct){
						tno=tot.textContent.slice(3).match(/[^\s]+/g);
						tot.innerHTML="";
					}else{
						tno=no[i].querySelectorAll(sTg);
					}
				}else{
					tno=no[i].querySelectorAll(sTg);
				}
				for(let j=0;j<tno.length;j++){
					let tag;
					if(tot&&!tct){
						tag=tno[j];
						tot.innerHTML+='<span id="tag_'+j+'">'+tag+'</span>';
					}else{
						tag=tno[j].textContent;
					}
					//console.log(tag);
					rBk=tot&&!tct?CHK(no[i].querySelector("span#tag_"+j),"t",T,tag):CHK(tno[j],"t",T,tag);
					if(rBk)break;
				}
			}
			// Blocked show type
			no[i].style.display=!V&&rBk?"none":"";
			no[i].style.opacity=V&&rBk?"0.5":"1";
		}
	}
	// Check keyword
	function CHK(e,n,l,s){
		const r=l.some((v)=>s===v);
		if(!e.classList.contains("c_h_k")){
			e.classList.add("c_h_k");
			e.setAttribute("data-r",n+s);
		}
		if(V){
			e.style.border=r?"thin solid fuchsia":"thin solid dodgerblue";
		}else{
			e.style.border="none";
		}
		return r;
	}

	// Select mode
	function SVM(){
		const bt=document.getElementById("r_fcb");
		if(!V){
			V=true;
			bt.textContent="📙";
			document.addEventListener("click",ECH);
			URD();
		}else{
			V=false;
			bt.textContent="📘";
			document.removeEventListener("click",ECH);
			// Auto save list
			USV();
		}
		FMD();
	}
	// Handler
	function ECH(e){
		e.preventDefault();
		const eT=e.target;
		const tE=eT.classList.contains("c_h_k")?eT
					:eT.parentElement.classList.contains("c_h_k")?eT.parentElement
					:null;
		//console.log(tE);
		if(tE){
			const tda=tE.getAttribute("data-r");
			const tlst=tda.slice(0,1)==="a"?A:T;
			const tid=tda.slice(1);
			const li=tlst.findIndex((v)=>v===tid);
			if(li!==-1){
				tlst.splice(li,1);
			}else{
				tlst.push(tid);
			}
			FMD();
		}
	}

	// Update Blocklists List
	function UBL(){
		alert(gMk+":"+localStorage.getItem(gMk));
	}
	// Sort Blocklists List
	function SBL(){
		A.sort();
		T.sort();
		USV();
		UBL();
	}
	// Delete Block List
	function DBL(){
		const t=prompt("Delete?","No");
		if(t==="Yes"){
			localStorage.removeItem(gMk);
			URD();
			UBL();
			FMD();
		}
	}
	// Create Float Button
	function CFB(){
		BCR("r_fcb","📘","2","2");
		BCR("r_ubl","♻","4","2");
		BCR("r_dbl","📛","4","4");
		BCR("r_sbl","🔀","2","4");
		document.addEventListener("click",BLM);
	}
	function BLM(e){
		switch(e.target.id){
			case "r_fcb":
				SVM();
				break;
			case "r_ubl":
				UBL();
				break;
			case "r_dbl":
				DBL();
				break;
			case "r_sbl":
				SBL();
				break;
		}
	}
	// Button creater
	function BCR(id,text,x,y){
		const cb=document.body.appendChild(document.createElement("button"));
		cb.id=id;
		cb.textContent=text;
		cb.style="position:fixed;width:44px;height:44px;z-index:999;font-size:200%;opacity:50%;cursor:pointer;right:"+x+"em;bottom:"+y+"em;";
		cb.type="button";
	}
})();