Greasy Fork is available in English.
Novel Ranking Filtering Bookmarklet for Mobile Browser
当前为
// ==UserScript==
// @name Novel Ranking Filter [No GM_API Version]
// @name:ja 小説ランキングフィルター [GM_APIなし]
// @namespace http://greasyfork.icu/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);
})();