// ==UserScript==
// @name Content Filter
// @name:ja コンテンツフィルター
// @namespace https://gf.qytechs.cn/en/users/1264733
// @version 2024-04-14
// @description Hide not interested content
// @description:ja 興味のない内容を隠す
// @author LE37
// @license MIT
// @include https://forum.palemoon.org/viewforum*
// @include https://forum.palemoon.org/viewtopic*
// @include https://forum.vivaldi.net/category/*
// @include https://forum.vivaldi.net/topic/*
// @include https://kakuyomu.jp/pickup_works*
// @include https://kakuyomu.jp/rankings/*
// @include https://kakuyomu.jp/recent_works*
// @include https://kakuyomu.jp/works/*/comments*
// @include https://kakuyomu.jp/works/*/episodes/*
// @include https://novelcom.syosetu.com/impression/*
// @include https://yomou.syosetu.com/rank/*
// @include https://syosetu.org/?mode=rank*
// @include https://syosetu.org/?mode=review*
// @include https://www.alphapolis.co.jp/novel/index*
// @include https://www.alphapolis.co.jp/novel/ranking/*
// @include https://www.alphapolis.co.jp/novel/*/comment*
// @include https://www.ign.com/articles/*
// @include https://www.yandex.com/search/*
// @include https://yandex.com/search/*
// @exclude https://www.alphapolis.co.jp/novel/ranking/annual
// @exclude https://yomou.syosetu.com/rank/top/
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(()=>{
'use strict';
// GM Key
let gMk;
switch (location.host) {
case "www.alphapolis.co.jp":
gMk = "APS";
break;
case "syosetu.org":
gMk = "HML";
break;
case "www.ign.com":
gMk = "IGN";
break;
case "kakuyomu.jp":
gMk = "KYU";
break;
case "novelcom.syosetu.com":
gMk = "NUC";
break;
case "yomou.syosetu.com":
gMk = "NRK";
break;
case "forum.palemoon.org":
gMk = "PMF";
break;
case "forum.vivaldi.net":
gMk = "VVF";
break;
case "yandex.com":
case "www.yandex.com":
gMk = "YDX";
break;
default:
//console.log("DoNothing");
}
if (gMk) {
RUN();
}
function RUN() {
// GM Menu
GM_registerMenuCommand("View", SVM);
GM_registerMenuCommand("Save", USV);
// ShadowsRoot, FireTime, MutationObserverNode, IntersectionObserverNode, Node, UserLink, UserID, Tag, Alter;
let cSr, cFt, eOn, eIo, eNo, eUl, sId, sTg, eAt;
// Client Type
const rMb = navigator.userAgent.includes("Mobile");
const uRi = location.href;
switch (gMk) {
case "APS":
// Alphapolis
cFt = 0;
if (uRi.includes("comment")) {
// Comments
eNo = "div.comment";
eUl = "span.name>a";
} else {
// Ranking
eNo = "div.section";
eUl = "div.author>a";
sTg = "li.tag a";
}
sId = /detail\/(\d+)$/;
break;
case "HML":
// Hameln
cFt = 0;
eNo = rMb ? "div.search_box" : "div.section3";
if (uRi.includes("rank")) {
// Ranking
eUl = "div.blo_title_sak a";
sTg = "div.all_keyword:nth-child(9) a";
} else {
// Comments
eUl = "h3>a:nth-child(1)";
}
sId = /((?<=uid=).*|(\d+)(?=\/))/;
break;
case "IGN":
// IGN
cSr = 1;
cFt = 3;
eIo = '#comments-section';
eOn = '.spcv_conversation';
eNo = "li";
eUl = null;
eAt = 'span[data-spot-im-class="message-username"]';
sId = /(.*)/;
break;
case "KYU":
// Kakuyomu
if (uRi.includes("/pickup") || uRi.includes("/rank") || uRi.includes("/recent")) {
// Ranking
cFt = 0;
eNo = "div.widget-work";
eUl = "a.widget-workCard-authorLabel";
sId = /users\/(.*)$/;
sTg = "a[itemprop='keywords']";
} else if (uRi.includes("comments")) {
// Comments
cFt = 2;
eOn = '#__next';
eNo = rMb ? 'div[class^="NewBox_box__"]>ul>li' : 'ul:nth-child(1) li';
eUl = 'div.partialGiftWidgetActivityName>a';
} else {
// Comments in Episode
cFt = 2;
eOn = "#episodeFooter-cheerComments-panel-mainContents";
eNo = "ul.widget-cheerCommentList li";
eUl = "h5.widget-cheerComment-author a";
}
sId = /users\/(.*)$/;
break;
case "NUC":
// Narou Comments
cFt = 0;
eNo = rMb ? "div.impression" : "div.waku";
eUl = "div.comment_authorbox>div>a";
eAt = "div.comment_authorbox>div";
sId = /\/(\d+)/;
break;
case "NRK":
// Narou Ranking
cFt = 0;
eNo = "div.p-ranklist-item";
eUl = "div.p-ranklist-item__author a";
sId = /\/(\d+)/;
sTg = "div.p-ranklist-item__keyword a";
break;
case "PMF":
// Palemoon Forum
cFt = 0;
if (uRi.includes("viewtopic")) {
// Topic
eNo = "#page-body div.post";
eUl = 'a[class^="username"]';
sId = /u=(\d+)/;
} else {
// Index
eNo = "ul.topiclist>li";
eUl = "div.topic-poster>a";
sId = /u=(\d+)/;
}
break;
case "VVF":
// Vivaldi Forum
cFt = 0;
if (uRi.includes("topic")) {
// Topic
eNo = "ul.posts>li";
eUl = "small.d-flex a";
sId = /user\/(.*)/;
} else {
// Index
eNo = "ul.topic-list li";
eUl = "small.hidden-xs>a";
sId = /user\/(.*)/;
}
break;
case "YDX":
// Yandex Search
cFt = 0;
eNo = rMb ? "div.serp-item" : "#search-result>li";
eUl = rMb ? null : "div.Path>a.Link";
eAt = "span.Path-Item>b";
sId = rMb ? /(.*)/ : /\/([^\/]+)/;
break;
}
// Read List
const URD = GM_getValue(gMk);
let tlo = URD ? URD : { BAL:[], BTL:[] };
const tal = tlo.BAL;
const ttl = tlo.BTL;
// Save List
function USV() {
tlo = { BAL:tal, BTL:ttl };
GM_setValue(gMk, tlo);
}
// Select View
let cSv = 0;
// Script Fire Time
switch (cFt) {
case 1:
RSC();
break;
case 2:
MOC();
break;
case 3:
IOC();
break;
case 0:
default:
FTR();
}
// ReadyState
function RSC() {
document.addEventListener("readystatechange", (e) => {
if (e.target.readyState === "complete") {
FTR();
}
});
}
// MutationObserver
function MOC() {
const obs = new MutationObserver(() => {
FTR();
//obs.disconnect();
});
// Shadowroot fix
const obn = cSr ? document.querySelector('div[data-spotim-module]').firstElementChild.shadowRoot.querySelectorAll(eOn)[0] : document.querySelector(eOn);
obs.observe(obn, {
childList: true,
subtree: true
});
}
// IntersectionObserver
function IOC() {
const ioc = new IntersectionObserver((entries) => {
if (entries[0].intersectionRatio <= 0) return;
FTR();
// IGN fix
if (gMk === "IGN") {
MOC();
}
ioc.disconnect();
});
ioc.observe(document.querySelector(eIo));
}
// Filtering
function FTR() {
// Shadowroot fix
// ShadowHost, ShadowRoot
let eSh, eSr;
if (cSr) {
eSh = document.querySelector('div[data-spotim-module]').firstElementChild;
if (eSh) {
eSr = eSh.shadowRoot;
}
//console.log(eSr);
}
const no = cSr ? eSr.querySelectorAll(eNo) : 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 === "NUC") {
// Narou nologin user fix?????????????
if (!eLk) {
eLk = no[i].querySelector(eAt);
uId = no[i].querySelector(eAt).textContent.split("\n")[2];
} else {
uId = eUl ? eLk.href.match(sId)[1] : eLk.textContent.match(sId)[1];
}
//console.log(uId);
rBk = CHK(eLk, tal, uId);
}
if (!rBk) {
// Filtering content contain multiple tags(text)
// N18 fix
const tno = no[i].querySelectorAll(sTg);
if (tno !== null) {
for (let j = 0; j < tno.length; j++) {
const tag = tno[j].textContent;
//console.log(tag);
rBk = CHK(tno[j], ttl, tag);
if (rBk) {
break;
}
}
}
}
// Blocked Show Type
if (cSv === 0) {
no[i].style.visibility = rBk ? "hidden" : "visible";
no[i].style.opacity = "1";
} else {
no[i].style.visibility = "visible";
no[i].style.opacity = rBk ? "0.5" : "1";
}
}
}
// CheckKeyword
function CHK(ele, l, s) {
const result = l.some((v) => s === v);
if (cSv === 1) {
ele.style.border = result ? "thin solid lime" : "thin solid red";
} else {
ele.style.border = "none";
}
return result;
}
// SelectViewMode
function SVM() {
if (cSv === 0) {
cSv = 1;
// Disable default click
document.addEventListener("click", PAC, true);
} else {
cSv = 0;
// Disable default click
document.removeEventListener("click", PAC, true);
// AutoSave
//USV();
}
FTR();
}
// PreventAnchorChange
function PAC(e) {
e.preventDefault();
e.stopPropagation();
const targetElement = cSr ? e.composedPath()[0] : e.target;
//console.log(targetElement);
const eLk = eUl ? eUl : eAt;
if (targetElement.closest(eLk)) {
let ai;
// Yandex fix
if (gMk === "YDX") {
ai = targetElement.href ? targetElement.href.match(sId)[1] : targetElement.parentElement.href.match(sId)[1];
} else {
ai = eUl ? targetElement.href.match(sId)[1] : targetElement.textContent.match(sId)[1];
}
UTL(e, ai, tal);
} else if (targetElement.closest(sTg)) {
const kd = targetElement.textContent;
UTL(e, kd, ttl);
}
FTR();
return false;
}
// UpdateTempList
function UTL(e, s, l) {
const li = l.findIndex((v) => v === s);
if (li !== -1) {
l.splice(li,1);
} else {
l.push(s);
}
//console.log(l);
return l;
}
}
})();