小説ランキングフィルター [GM_APIなし]

モバイルブラウザ用小説ランキングフィルタリングブックマークレット

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name           Novel Ranking Filter [No GM_API Version]
// @name:ja        小説ランキングフィルター [GM_APIなし]
// @namespace      https://greasyfork.org/en/users/1264733
// @version        2024-05-05
// @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/rankings/*
// @include        https://kakuyomu.jp/*recent_works
// @include        https://syosetu.org/?mode=rank*
// @include        https://yomou.syosetu.com/rank/*
// @exclude        https://www.alphapolis.co.jp/novel/ranking/annual
// @exclude        https://yomou.syosetu.com/rank/top/
// @grant          none
// ==/UserScript==

(function() {
	'use strict';
	// a_k: SiteKey, a_l: AuthorLink, a_r: RegForAuthorID, n_n: NovelNode, t_n: Tag;
	// rMb: Client type(Mobile/Desktop)
	const rMb = navigator.userAgent.includes("Mobile");
	let a_k, a_l, a_r, n_n, t_n;
	switch (location.host) {
		case "www.alphapolis.co.jp":
			a_k = "A";
			a_l = "div.author>a";
			a_r = /detail\/(\d+)$/;
			n_n = "div.section";
			t_n = "li.tag a";
			break;
		case "syosetu.org":
			a_k = "H";
			a_l = rMb ? "p:nth-child(2)" : "div.blo_title_sak";
			a_r = /:(.*)/;
			n_n = rMb ? "div.search_box" : "div.section3";
			t_n = rMb ? 'span[id^="tag_"]' : 'div.all_keyword:nth-child(9) a';
			break;
		case "kakuyomu.jp":
			a_k = "K";
			a_l = "a.widget-workCard-authorLabel";
			a_r = /users\/(.*)$/;
			n_n = "div.widget-work";
			t_n = "a[itemprop='keywords']";
			break;
		case "yomou.syosetu.com":
			a_k = "N";
			a_l = "div.p-ranklist-item__author a";
			a_r = /\/(\d+)/;
			n_n = "div.p-ranklist-item";
			t_n = "div.p-ranklist-item__keyword a";
			break;
	}
	// Read List
	const G = JSON.parse(localStorage.getItem(a_k));
	let O = G ? G : { AL:[], TL:[] };
	// ga: Disliked Author List
	let ga = O.AL;
	// gt: Disliked Tag List;
	let gt = O.TL;
	// Save List
	function S() {
		O = { AL:ga, TL:gt };
		localStorage.setItem(a_k, JSON.stringify(O));
	}
	// Sort List
	function ST() {
		ga.sort();
		gt.sort();
		S();
	}
	// Select Mode
	let s_m = 0;
	// Run
	NM();
	// Normal Mode
	function NM() {
		const no = document.querySelectorAll(n_n);
		for (let i = 0; i < no.length; i++) {
			let b = false;
			const al = no[i].querySelector(a_l);
			if (al) {
				// Hameln author fix
				const ai = (a_k === "H") ? al.textContent.match(a_r)[1] : al.href.match(a_r)[1];
				//console.log(ai);
				b = CHK(al, ga, ai);
			}
			let tl;
			// Hameln tag fix
			// Convert origin text to custom tags for mobile
			let tot, tct;
			if (a_k === "H" && rMb) {
				tot = no[i].querySelector(".trigger p:nth-child(4)");
				tct = no[i].querySelector(t_n);
				tl = (!tct) ? tot.textContent.slice(3).match(/[^\s]+/g) : no[i].querySelectorAll(t_n);
				if (!tct) tot.innerHTML = "";
			} else {
				tl = no[i].querySelectorAll(t_n);
			}
			if (!b && tl) {
				for (let j = 0; j < tl.length; j++) {
					let tag;
					// Hameln fix
					if (tot && !tct) {
						tag = tl[j];
						tot.innerHTML += '<span id="tag_' + j + '">' + tag + '</span>';
					} else {
						tag = tl[j].textContent;
					}
					//console.log(tag);
					b = tot && !tct ? CHK(no[i].querySelector("span#tag_"+j), gt, tag) : CHK(tl[j], gt, tag);
					if (b) break;
				}
			}
			no[i].style.display = s_m === 0 && b ? "none" : "";
			no[i].style.opacity = s_m === 1 && b ? "0.5" : "1";
		}
	}
	// Check Keyword
	function CHK(elem, l, s) {
		const result = l.some((v) => s === v);
		if (s_m === 1) {
			elem.style.border = result ? "thin solid fuchsia" : "thin solid dodgerblue";
		} else {
			elem.style.border = "none";
		}
		return result;
	}
	// Select Mode
	function SM() {
		//console.log(a_k + ": " + ga + "\nTG: " + gt);
		if (s_m === 0) {
			s_m = 1;
			// Disable default click
			document.addEventListener("click", UH, true);
		} else {
			s_m = 0;
			// Restore default click
			document.removeEventListener("click", UH, true);
			S();
		}
		NM();
	}
	// Update Handler
	function UH(e) {
		e.preventDefault();
		if (e.target.closest(a_l)) {
			// Hameln fix
			const tai = (a_k === "H") ? e.target.textContent.match(a_r)[1] : e.target.href.match(a_r)[1];
			//console.log(tai);
			UT(e, tai, ga);
			NM();
		} else if (e.target.closest(t_n)) {
			UT(e, e.target.textContent, gt);
			NM();
		}
		return false;
	}
	// Update Temp
	function UT(e, s, l) {
		const li = l.findIndex((v) => v === s);
		if (li !== -1) {
			l.splice(li,1);
		} else {
			l.push(s);
		}
		return l;
	}
	// Custom Button
	const bba = document.body.appendChild(document.createElement("button"));
	bba.id = "bmi";
	bba.textContent = "📘";
	// Button Style
	bba.style = "position: fixed; bottom: 20%; right: 10%; width: 44px; height: 44px; z-index: 9999; font-size: 200%; opacity: 50%;";
	bba.type = "button";
	bba.addEventListener("click", SM, true);
})();