Novel Ranking Filter [No GM_API Version]

Novel Ranking Filtering Bookmarklet for Mobile Browser

目前为 2024-06-19 提交的版本。查看 最新版本

// ==UserScript==
// @name           Novel Ranking Filter [No GM_API Version]
// @name:ja        小説ランキングフィルター [GM_APIなし]
// @namespace      https://gf.qytechs.cn/en/users/1264733
// @version        2024-06-19
// @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==

(()=>{
	/*LS20240619*/
	'use strict';
	// GM key, Nodelist, userLink, userid, tag, alt;
	let gMk, eNo, eUl, sId, sTg, eAt;
	// View mode 
	let cSv = false;
	// Show/hide Blocklist
	let sFb = false;
	// Client type
	const rMb = navigator.userAgent.includes("Mobile");
	const path = 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 = rMb ? "div.search_box" : "div.section3";
			eUl = null;
			sId = /:(.*)/;
			sTg = rMb ? 'span[id^="tag_"]' : 'div.all_keyword:nth-child(9) a';
			eAt = rMb ? "p:nth-child(2)" : "div.blo_title_sak";
			break;
		case "kakuyomu.jp":
			gMk = "K";
			sId = /users\/(.*)$/;
			if (path.startsWith("/search")) {
				eNo = rMb ? 'div[class*="Spacer_margin-ml-m__"]' : 'div[class*="NewBox_borderSize-bb"]';
				eUl = rMb ? 'span[class*="workLabelAuthor__"] a' : "div.partialGiftWidgetActivityName>a";
				sTg = 'a[href^="/tags/"]';
			} else if (path.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 (path.startsWith("/search")) {
				eNo = rMb ? "div.smpnovel_list" : "div.searchkekka_box";
				eUl = rMb ? null : "a:nth-child(2)";
				sId = rMb ? /:(.*)/ : /\/(\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
	const G = JSON.parse(localStorage.getItem(gMk));
	let O = G ? G : { AL:[], TL:[] };
	let tal = O.AL;
	let ttl = O.TL;
	// Save list
	function USV() {
		O = { AL:tal, TL:ttl };
		localStorage.setItem(gMk, JSON.stringify(O));
	}
	// Sort list
	function UST() {
		tal.sort();
		ttl.sort();
		USV();
	}
	const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
	// Script fire time
	if (gMk === "K" && path.startsWith("/search")) {
		sleep(1500).then(() => FMD());
	} else {
		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" && rMb) ) {
				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", tal, 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" && rMb) {
					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", ttl, tag) : CHK(tno[j], "t", ttl, tag);
					if (rBk) break;
				}
			}
			// Blocked show type
			no[i].style.display = !cSv && rBk ? "none" : "";
			no[i].style.opacity = cSv && rBk ? "0.5" : "1";
		}
	}
	// Check keyword
	function CHK(ele, n, l, s) {
		const r = l.some((v) => s === v);
		if (!ele.classList.contains("c_h_k")) {
			ele.classList.add("c_h_k");
			ele.setAttribute("data-lkw", n + s);
		}
		if (cSv) {
			ele.style.border = r ? "thin solid fuchsia" : "thin solid dodgerblue";
		} else {
			ele.style.border = "none";
		}
		return r;
	}

	// Select mode
	function SVM() {
		const btn = document.getElementById("nrf_fcb");
		if (!cSv) {
			cSv = true;
			btn.textContent = "📙";
			document.addEventListener("click", ECH);
		} else {
			cSv = false;
			btn.textContent = "📘";
			document.removeEventListener("click", ECH);
			// Auto save list
			USV();
		}
		FMD();
	}
	// Handler
	function ECH(e) {
		e.preventDefault();
		const tEle = e.target.classList.contains("c_h_k") ? e.target
					: e.target.parentElement.classList.contains("c_h_k") ? e.target.parentElement
					: null;
		//console.log(tEle);
		if (tEle) {
			const tda = tEle.getAttribute("data-lkw");
			const tlst = tda.slice(0, 1) === "a" ? tal : ttl;
			const tid = tda.slice(1);
			const li = tlst.findIndex((v) => v === tid);
			if (li !== -1) {
				tlst.splice(li,1);
			} else {
				tlst.push(tid);
			}
			FMD();
		}
	}

	// Create Blocklists Menu
	function CBM() {
		if (!document.getElementById("nrf_blm")) {
			const cbl = document.body.appendChild(document.createElement("div"));
			const pos = !rMb ? " width: 50%; left: 25%;" : " width: 98%; left: 1%;";
			cbl.id = "nrf_blm";
			cbl.style = "position: fixed;" + pos + " overflow-y: scroll; height: 52%; top:10%; z-index: 9999; background-color: #f1f3f5; display: none;";
		}
		const blm = document.getElementById("nrf_blm");
		if (!sFb) {
			sFb = true;
			UBM();
			blm.style.display = "";
			blm.addEventListener("click", DBL);
		} else {
			sFb = false;
			blm.style.display = "none";
			blm.removeEventListener("click", DBL);
			blm.innerHTML = "";
		}
	}
	// Delete Block List
	function DBL(e) {
		if (e.target.classList.contains("nrf_dbl")) {
			const key = e.target.textContent;
			localStorage.removeItem(key);
			UBM();
			// Delete current
			if (key === gMk) {
				// Delete cache
				tal = [];
				ttl = [];
				USV();
				FMD();
			}
		}
	}
	// Update Blocklists Menu
	function UBM() {
		const blm = document.getElementById("nrf_blm");
		blm.innerHTML = "";
		Object.keys(localStorage).forEach(k => {
			blm.innerHTML += '<p style="margin-left: 1em; font-size: 1em; line-height: 2em;">' +
								'<span class="nrf_dbl" type="button" style="color: red; cursor: pointer;">' + k + '</span>' + 
								'<span>: ' + localStorage.getItem(k) + '</span>' + 
							'</p>';
		});
	}

	// Create Float Button
	function CFB() {
		const btn = document.body.appendChild(document.createElement("button"));
		// Button Style
		btn.id = "nrf_fcb";
		btn.textContent = "📘";
		btn.style = "position: fixed; bottom: 2em; right: 2em; width: 44px; height: 44px; z-index: 9999; font-size: 200%; opacity: 50%; cursor:pointer; border: none; padding: unset;";
		btn.type = "button";
		btn.addEventListener("click", (e) => { SVM(); });
		btn.addEventListener("dblclick", (e) => { CBM(); });
	}
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址