Content Filter

Hide not interested content

От 14.04.2024. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name           Content Filter
// @name:ja        コンテンツフィルター
// @namespace      https://greasyfork.org/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);
		// cSr: ShadowsRoot, cFt: FireTime, eOn: MutationObserverNode, eIo: IntersectionObserverNode, eNo: Node, eUl: UserLink, sId: UserID, sTg: Tag, eAt: 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 spotim 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 spotim 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)
					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);
			let eLk;
			// Narou nologin user fix
			if (gMk === "NUC") {
				eLk = targetElement.href ? eUl : eAt;
			} else {
				eLk = eUl ? eUl : eAt;
			}
			if (targetElement.closest(eLk)) {
				let ai;
				switch (gMk) {
					// Narou nologin user fix
					case "NUC":
						ai = targetElement.href ? targetElement.href.match(sId)[1] : targetElement.textContent.split("\n")[2];
						break;
					// Yandex fix
					case "YDX":
						ai = targetElement.href ? targetElement.href.match(sId)[1] : targetElement.parentElement.href.match(sId)[1];
						break;
					default:
						ai = eUl ? targetElement.href.match(sId)[1] : targetElement.textContent.match(sId)[1];
				}
				//console.log(ai);
				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;
		}
	}
})();