// ==UserScript== // @name Novel Ranking Filter // @name:ja 小説ランキングフィルター // @namespace https://greasyfork.org/en/users/1264733 // @version 2024-05-05 // @description Alphapolis Hameln Kakuyomu Narou Ranking Page Filtering by AuthorID and Tag // @description:ja アルファポリス・ハーメルン・カクヨム・なろう 作者IDとタグによるランキングページの小説フィルタリング // @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 GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @downloadURL 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; } // GM Menu GM_registerMenuCommand("View", SM); GM_registerMenuCommand("Sort", ST); // Read List const G = GM_getValue(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 }; GM_setValue(a_k, 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 += '' + tag + ''; } 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); })();