// ==UserScript== // @name Content Filter // @name:ja コンテンツフィルター // @namespace https://greasyfork.org/en/users/1264733 // @version 2024-05-05 // @description Hide not interested content // @description:ja 興味のない内容を隠す // @author LE37 // @license MIT // @include https://* // @exclude https://kakuyomu.jp/my/* // @enclude https://syosetu.com/favnovelmain/* // @enclude https://www.alphapolis.co.jp/mypage/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @downloadURL none // ==/UserScript== (()=>{ 'use strict'; // GM Key let gMk; switch (location.host) { case "www.alphapolis.co.jp": gMk = "APS"; break; case "greasyfork.org": //case "": gMk = "GFK"; break; case "syosetu.org": gMk = "HML"; break; /*case "": gMk = "HTM"; break;*/ case "www.ign.com": gMk = "IGN"; break; case "kakuyomu.jp": gMk = "KYU"; break; /*case "": gMk = "NNN"; break;*/ case "novelcom.syosetu.com": gMk = "NUC"; break; case "mypage.syosetu.com": case "ncode.syosetu.com": case "yomou.syosetu.com": gMk = "NRK"; break; /*case "": case "": gMk = "PHB"; break;*/ case "forum.palemoon.org": gMk = "PMF"; break; /*case "": gMk = "SRB"; break;*/ case "forum.vivaldi.net": gMk = "VVF"; break; case "social.vivaldi.net": gMk = "VVS"; break; case "yandex.com": case "www.yandex.com": gMk = "YDX"; break; default: //console.log("DoNothing"); } if (gMk) { RUN(); } function RUN() { // cSr: Filting shadowroot content, only used when target within shadowroot // 0:off[default] 1:on let cSr = 0; // Shadowhost, Shadowroot, used when cSr = 1 let eSh , eSr; // cAp: Filtering author/novel page // 0:off[default] 1:on let cAp = 0; // Select mode, 0:off[default] 1:on let cSv = 0; // cFt: Script firetime, prevent script fires too early // 0:Normal[default] 1:ReadyState Complete 2:MutationObserver 3:IntersectionObserver let cFt = 0; // eOn: MutationObserver targetNode, used when cFt = 2 let eOn; // eIo: IntersectionObserver target, used when cFt = 3 let eIo; // eNo: target nodelist, eUl: userLink, sId: userID, sTg: tag let eNo, eUl, sId, sTg; // eAt: Alternate text(target's textContent), used when predefine eUl(userlink) doen't contain valid href let eAt; // rMb: Client type // true:Mobile false:Desktop const rMb = navigator.userAgent.includes("Mobile"); // cAd: Additional Delay // 0:off[default] 1:on let cAd = 0; const uRi = location.href; switch (gMk) { case "APS": // Alphapolis if (uRi.includes("comment")) { // Comments eNo = "div.comment"; eUl = "span.name>a"; } else if (uRi.includes("index") || uRi.includes("ranking")) { // Ranking eNo = "div.section"; eUl = "div.author>a"; sTg = "li.tag a"; } else if (uRi.includes("author") || (/novel[0-9\/]+$/).test(uRi)) { // Author Page cAp = 1; eUl = uRi.includes("author") ? "div.name>h1" : "div.author a"; } sId = /detail\/(\d+)$/; break; case "GFK": // Greasyfork if (uRi.includes("/scripts")) { // Scripts eNo = "li[data-script-id]"; // Script link eUl = "a.script-link"; // Script authors sTg = "dd.script-list-author a"; } else if (uRi.includes("/discussions")) { // Discussions eNo = "div.discussion-list-container"; // Discussion link eUl = "a.script-link"; // Discussion author sTg = "a.user-link"; } sId = /s\/(\d+)/; break; case "HML": // Hameln eNo = rMb ? "div.search_box" : "div.section3"; if (uRi.includes("rank")) { // Ranking eUl = null; eAt = rMb ? "p:nth-child(2)" : "div.blo_title_sak"; sId = /:(.*)/; sTg = rMb ? 'span[id^="tag_"]' : 'div.all_keyword:nth-child(9) a'; } else if (uRi.includes("review")) { // Comments eUl = null; eAt = rMb ? "h4" : "h3"; sId = /([^\s]+)/; } else if ((/novel|user\/\d+\/$/).test(uRi)) { // Author Page cAp = 1; eUl = null; if (/novel\/\d+\/$/.test(uRi)) { eAt = 'span[itemprop="author"]' } else { eAt = rMb ? 'h3>a' : 'h3'; } sId = /([^/]+)/; } break; /*case "HTM": // cFt = 2; eOn = "div.gallery-content"; eNo = "div.gallery-content>div"; eUl = "table.dj-desc tr:nth-child(3) td:nth-child(2) a"; sId = /index-(\w+)\.html/; sTg = "td.relatedtags>ul>li"; break;*/ case "IGN": // IGN cSr = 1; cFt = 2; eOn = 'body'; 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 eNo = "div.widget-work"; eUl = "a.widget-workCard-authorLabel"; sId = /users\/(.*)$/; sTg = "a[itemprop='keywords']"; } else if (uRi.includes("comments")) { // Comments cAd = 1; eNo = rMb ? 'div[class^="NewBox_box__"]>ul>li' : 'ul:nth-child(1) li'; eUl = 'div.partialGiftWidgetActivityName>a'; } else if (uRi.includes("episodes")) { // Comments in Episode cFt = 2; eOn = "#episodeFooter-cheerComments-panel-mainContents"; eNo = "ul.widget-cheerCommentList li"; eUl = "h5.widget-cheerComment-author a"; } else if (uRi.includes("users") || (/works\/\d+$/).test(uRi)) { // Author Page cAd = 1; cAp = 1; eUl = uRi.includes("users") ? 'div[class^="HeaderText"]>a' : 'div.partialGiftWidgetActivityName>a'; } sId = /users\/(.*)$/; break; /*case "NNN": // eNo = rMb ? "ul.ranking" : "div.rank_h"; eUl = null; eAt = rMb ? "li:nth-child(2)" : "span.name"; sId = /.{3}(.*)/; sTg = rMb ? "li.keyword a" : "td.s a"; break;*/ case "NUC": // Narou Comments eNo = rMb ? "div.impression" : "div.waku"; eUl = "div.comment_authorbox>div>a"; eAt = "div.comment_authorbox>div"; sId = /\/(\d+)/; break; case "NRK": // Narou Ranking if (uRi.includes("mypage") || uRi.includes("ncode")) { // Author Page cAp = 1; eUl = uRi.includes("ncode") ? 'div.novel_writername>a' : 'div.p-userheader__username'; } else { // Ranking eNo = "div.p-ranklist-item"; eUl = "div.p-ranklist-item__author a"; sTg = "div.p-ranklist-item__keyword a"; } sId = /\/(\d+)/; break; /*case "PHB": // eNo = rMb ? "div.videoWrapper" : "div.wrap"; eUl = rMb ? "a.uploaderLink" : "div.usernameWrap a"; sId = /([^\/]+)$/; break;*/ case "PMF": // Palemoon Forum 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 "SRB": // if (uRi.includes("thread")) { // Thread eNo = rMb ? 'div[id^="pid"]' : 'div[id^="post_"]:not([id^="post_rate"]):not([id^="post_new"])'; eUl = null; eAt = rMb ? "ul.authi a" : "a.xw1"; sId = /(.*)/; } else { // Index eOn = "#threadlisttableid"; eNo = rMb ? "div.threadlist>ul>li" : "table#threadlisttableid tbody"; eUl = null; eAt = rMb ? "span.by" : "td:nth-child(3)>cite>a"; sId = /(.*)/; } break;*/ case "VVF": // Vivaldi Forum 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 "VVS": // Vivaldi Social cFt = 2; eOn = "body"; eIo = ".load-more"; eNo = "div.item-list>article"; eUl = null; eAt = "strong.display-name__html"; sId = /(.*)/; break; case "YDX": // Yandex Search eNo = rMb ? "div.serp-item" : "#search-result>li"; eUl = rMb ? null : "div.Path>a.Link"; eAt = "span.Path-Item>b"; sId = rMb ? /(.*)/ : /\/([^\/]+)/; break; } // GM Menu GM_registerMenuCommand("View", SVM); GM_registerMenuCommand("Sort", UST); // 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); } // Sort List // mapsort??? function UST() { tal.sort(); ttl.sort(); USV(); } const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // Script Fire Time switch (cFt) { case 1: // ReadyState complete RSC(); break; case 2: // MutationObserver MOC(); break; case 3: // IntersectionObserver IOC(); break; case 0: default: if (cAd) { // Delay wait(1500).then(() => FMD()); } else { // Normal FMD(); } /* if (gMk === "SRB" && !rMb && !uRi.includes("thread")) { MOC(); }*/ } // ReadyState complete function RSC() { document.addEventListener("readystatechange", (e) => { if (e.target.readyState === "complete") { //console.log('RSC: Complete'); } }); } // MutationObserver function MOC() { if (gMk === "KYU") { // Comments in Episode // Button load comments const bLc = document.querySelector('#episodeFooter-action-cheerCommentsButton'); bLc.addEventListener("click", (e) => { waitForElement(eNo, 2000).then(() => { //console.log('MOC: Ready'); FTR(); }).catch(() => { //console.log('MOC: Timeout'); }); }); } else { waitForElement(eNo, 30000).then(() => { //console.log('MOC: Ready'); FMD(); // IGN news if (gMk === "IGN") { // Button load more messages const bLm = eSr.querySelector('.spcv_load-more-messages'); bLm.addEventListener("click", (e) => { wait(2000).then(() => FTR()); }); } // Vivaldi Social if (gMk === "VVS") { wait(1500).then(() => IOC()); } }).catch(() => { //console.log('MOC: Timeout'); }); } } // Wait for an element to be loaded function waitForElement(selector, timeout) { return new Promise((resolve, reject) => { var timer = false; // Spot im shadownode if (cSr) { if (eSr) { if (eSr.querySelectorAll(selector).length) { return resolve(); } } } else { if (document.querySelectorAll(selector).length) return resolve(); } const obs = new MutationObserver(mutations => { // Spot im shadownode if (cSr) { eSh = document.querySelector('div[data-spotim-module]').firstElementChild; if (eSh) { eSr = eSh.shadowRoot; if (eSr) { if (eSr.querySelectorAll(selector).length) { obs.disconnect(); if (timer !== false) clearTimeout(timer); return resolve(); } } } } else { if (document.querySelectorAll(selector).length) { obs.disconnect(); if (timer !== false) clearTimeout(timer); return resolve(); } } }); // Spot im shadownode const obn = eSr ? eSr.querySelectorAll('.spcv_conversation')[0] : document.querySelector(eOn); obs.observe(obn, { childList: true, subtree: true }); if (timeout) { timer = setTimeout(() => { obs.disconnect(); reject(); }, timeout); } }); } // IntersectionObserver function IOC() { const ioc = new IntersectionObserver((entries) => { if (entries[0].intersectionRatio <= 0) return; ioc.disconnect(); // Vivaldi Social if (gMk === "VVS") { wait(1500).then(() => MOC()); } }); ioc.observe(document.querySelector(eIo)); } // Filtering mode function FMD() { if (cAp) { // Filtering single target FAP(); } else { // Filtering multiple targets FTR(); } } // Filtering single target function FAP() { let rBk = false; const eLk = eUl ? document.querySelector(eUl) : document.querySelector(eAt); let uId; // Narou author page fix if (gMk === "NRK") { uId = eLk.href ? eLk.href.match(sId)[1] : uRi.match(sId)[1]; } else { uId = eUl ? eLk.href.match(sId)[1] : eLk.textContent.match(sId)[1]; } rBk = CHK(eLk, tal, uId); eLk.style.opacity = rBk ? "0.5" : "1"; eLk.style.color = rBk ? "red" : "lime"; } // Filtering multiple targets function FTR() { 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" || gMk === "VVS") { // Narou nologin user fix // Vivaldi Social element out of view fix if (!eLk) { eLk = gMk === "VVS" ? no[i].querySelector("span") : no[i].querySelector(eAt); uId = gMk === "VVS" ? eLk.textContent.match(sId)[1].replace(/\s/g,'') : eLk.textContent.split("\n")[2]; } else { uId = eUl ? eLk.href.match(sId)[1] : eLk.textContent.match(sId)[1]; // Vivaldi Social id fix for foreground & background if (gMk ==="VVS") { let emoji = ""; const ino = no[i].querySelectorAll(eAt + " img"); if (ino) { for (let k = 0; k < ino.length; k++) { emoji += ino[k].alt; } } uId = eLk.textContent.match(sId)[1] + emoji; uId = uId.replace(/\s/g,''); } } //console.log(uId); // Vivaldi Social use static no[i] instead of dynamic eLk rBk = gMk === "VVS" ? CHK(no[i], tal, uId) : CHK(eLk, tal, uId); } //const eNes = no[i].nextElementSibling; if (sTg && !rBk) { // Filtering content contain multiple tags(text) // Tag node let tno; // Hameln mobile origin tag, custom tag let tot, tct; if (gMk === "HML" && rMb) { tot = no[i].querySelector(".trigger p:nth-child(4)"); tct = no[i].querySelector(sTg); if (!tct) { tno = tot.textContent.slice(3).match(/[^\s]+/g); tot.innerHTML = ""; } else { tno = no[i].querySelectorAll(sTg); } } else { // NNN desktop fix tno = no[i].querySelectorAll(sTg);//gMk === "NNN" && !rMb ? eNes.querySelectorAll(sTg) : no[i].querySelectorAll(sTg); } for (let j = 0; j < tno.length; j++) { let tag; if (tot && !tct) { tag = tno[j]; tot.innerHTML += '' + tag + ''; } else { // Greasyfork fix tag = gMk === "GFK" ? tno[j].href.match(sId)[1] : tno[j].textContent; } //console.log(tag); /* HTM hidden tag fix if (gMk === "HTM" && tno[j].classList.length !== 0 || tag === "...") { break; }*/ rBk = tot && !tct ? CHK(no[i].querySelector("span#tag_"+j), ttl, tag) : CHK(tno[j], ttl, tag); if (rBk) { break; } } } // Blocked Show Type if (cSv === 0) { no[i].style.display = rBk ? "none" : ""; no[i].style.opacity = "1"; /* NNN desktop fix if (gMk === "NNN" && !rMb) { eNes.style.display = rBk ? "none" : ""; eNes.style.opacity = "1"; }*/ } else { no[i].style.display = ""; no[i].style.opacity = rBk ? "0.5" : "1"; /* NNN desktop fix if (gMk === "NNN" && !rMb) { eNes.style.display = ""; eNes.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 fuchsia" : "thin solid dodgerblue"; } else { ele.style.border = "none"; } return result; } // Select mode function SVM() { if (cSv === 0) { cSv = 1; // Disable default click document.addEventListener("click", PAC, true); } else { cSv = 0; // Enable default click document.removeEventListener("click", PAC, true); // Auto save list USV(); } FMD(); } // PreventAnchorChange function PAC(e) { e.preventDefault(); // Vivaldi Forum & Social fix if (gMk === "VVF" || gMk === "VVS") { 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; } // StopPropagation fix if (targetElement.closest("#cFbtn")) { SVM; } else if (targetElement.closest(eLk)) { let ai; switch (gMk) { // Narou author page fix case "NRK": if (uRi.includes("mypage")) { // Author Page ai = uRi.match(sId)[1]; } else { ai = eUl ? targetElement.href.match(sId)[1] : targetElement.textContent.match(sId)[1]; } break; // Narou nologin user fix case "NUC": ai = targetElement.href ? targetElement.href.match(sId)[1] : targetElement.textContent.split("\n")[2]; break; // Vivaldi Social different id fix case "VVS": let emoji = ""; const ino = targetElement.parentElement.querySelectorAll(eAt + " img"); if (ino) { for (let k = 0; k < ino.length; k++) { emoji += ino[k].alt; } } ai = targetElement.textContent.match(sId)[1] + emoji; ai = ai.replace(/\s/g,''); 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); FMD(); } else if (targetElement.closest(sTg)) { // Greasyfork fix const kd = gMk === "GFK" ? targetElement.href.match(sId)[1] : targetElement.textContent; //console.log(kd); UTL(e, kd, ttl); FMD(); } // IGN Popup temp fix if (gMk === "IGN") { wait(500).then(() => { const bsh = document.body.lastChild.shadowRoot; if (bsh) { const bsr = bsh.querySelector('button[title="Close the modal"]'); if (bsr) { bsr.click(); } } }); } 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; } // Create Float Button const cButton = document.body.appendChild(document.createElement("button")); // Button Style cButton.id = "cFbtn"; cButton.textContent = "📘"; cButton.style = "position: fixed; bottom: 20%; right: 10%; width: 44px; height: 44px; z-index: 9999; font-size: 200%; opacity: 50%;"; cButton.type = "button"; cButton.addEventListener("click", (e) => { SVM(); }); // Vivaldi Social CSP temp fix if (gMk === "VVF" || gMk === "VVS") { cButton.addEventListener("dblclick", (e) => { cSv = 1; SVM(); }); } } })();