Ignore an unlimited amount of users. Comes with custom settings: delete the entire post, replace the content of the message with a custom message, replace or delete the avatar, and keep or delete the signature.
// ==UserScript== // @name Unlimited MAL Ignore list // @namespace http://tampermonkey.net/ // @version 0.85 // @description Ignore an unlimited amount of users. Comes with custom settings: delete the entire post, replace the content of the message with a custom message, replace or delete the avatar, and keep or delete the signature. // @author Only_Brad // @author ShaggyZE // @match https://myanimelist.net/* // @run-at document-end // ==/UserScript== (function() { const FORUM_OPTIONS = "editprofile.php?go=forumoptions"; const POSTS_URL = "forum/?topicid"; const LAST_POST_URL = "forum"; const TOPICS_URL = "forum/?board"; const TOPICS_SEARCH_URL = "forum/search?"; const CLUB_TOPICS_URL_1 = "clubs.php"; const CLUB_TOPICS_URL_2 = "forum/?clubid"; const PROFILE_URL = "profile"; const COMTOCOM_URL = "comtocom.php"; const COMMENTS_URL = "comments.php"; const BLACKLIST_URL = "https://myanimelist.net/blacklist"; const BLACKLIST_KEY = "ignore-list"; const SETTINGS_KEY = "ignore-list-settings"; const YOU_SELECTOR = ".header-profile-link"; const POST_USERS_SELECTOR = ".profile"; const TOPIC_USERS_SELECTOR = ".forum_postusername a"; const MESSAGE_SELECTOR = ".content [id^=message]"; const QUOTE_SELECTOR = ".quotetext"; const AVATAR_SELECTOR = ".forum-icon"; const USER_PROFILE_SELECTOR = "[href^='/profile']"; const USER_INFO_SELECTOR = "[id^=messageuser]"; const USERINFO_SELECTOR = ".username"; const USERINFO_SELECTOR1 = ".userstatus"; const USERINFO_SELECTOR2 = ".userinfo.joined"; const USERINFO_SELECTOR3 = ".userinfo.posts"; const USERINFO_SELECTOR4 = ".custom-forum-title"; const USERINFO_SELECTOR5 = ".modified"; const USERINFO_SELECTOR6 = ".icon-team-title"; const SIGNATURE_SELECTOR = ".sig"; const FORUM_MESSAGE_SELECTOR = "[id^=msg]"; const FORUM_MSG_NAME_SELECTOR = ".username a"; const FORUM_QUOTE_NAME_SELECTOR = ".quotetext > strong > a"; const FORUM_ACTION_BAR_SELECTOR = "[id^=postEditButtons]"; const PROFILE_MSG_SELECTOR = "[id^=comBox]"; const PROFILE_MSG_NAME_SELECTOR = ".text a.fw-b"; const PROFILE_MSG_AVATAR_SELECTOR = ".image"; const PROFILE_MSG_TEXT_SELECTOR = ".text .comment-text"; const PROFILE_MSG_ACTION_BAR_SELECTOR = ".text > div.pb8 > a"; const COMTOCOM_SELECTOR = "[id^=comBox]"; const COMTOCOM_NAME_SELECTOR = ".dark_text a"; const COMTOCOM_AVATAR_SELECTOR = ".picSurround a"; const COMTOCOM_TEXT_SELECTOR = "[id^=comtext]"; const COMTOCOM_ACTION_BAR_SELECTOR = ".dark_text a"; const IGNORE = 0; const REPLACE = 1; const DO_NOTHING = 2; let blacklist; let settings; //routing if (window.location.href.includes(FORUM_OPTIONS)) { AddBlacklistLink(); } else if (window.location.href.includes(POSTS_URL)) { handlePosts(); handleQuotes(); } else if ( window.location.href.includes(TOPICS_URL) || window.location.href.includes(TOPICS_SEARCH_URL) || window.location.href.includes(CLUB_TOPICS_URL_1) || window.location.href.includes(CLUB_TOPICS_URL_2) ) { handleTopics(); } else if (window.location.href.includes(PROFILE_URL)) { handleProfileMsgs(); } else if (window.location.href.includes(COMTOCOM_URL)) { handleComToCom(); } else if (window.location.href.includes(COMMENTS_URL)) { handleComToCom(); } else if (window.location.href === BLACKLIST_URL) { handleBlacklist(); } else if (window.location.href.includes(LAST_POST_URL)) { handleLastPost(); } //GM_addStyle equivalent that works on firefox function addStyle(css) { const style = document.getElementById("addStyleBy8626") || (function() { const style = document.createElement('style'); style.type = 'text/css'; style.id = "addStyleBy8626"; document.head.appendChild(style); return style; })(); style.innerHTML += css; } //helper functions to load from localStorage function loadBlackList() { blacklist = JSON.parse(localStorage.getItem(BLACKLIST_KEY)) || []; } function saveBlackList() { localStorage.setItem(BLACKLIST_KEY, JSON.stringify(blacklist)); } function loadSettings() { settings = JSON.parse(localStorage.getItem(SETTINGS_KEY)) || { replaceUsername: false, replaceAvatar: false, replaceProfileAvatar: false, removeSignatures: true, removeUserinfo: true, quoteMode: IGNORE, postMode: REPLACE, profileMsgMode: IGNORE, removeTopics: true, UnBlacklistUsername: false, removeUnBlacklist: false, customLastPost: "", customQuote: "", customPost: "", customAvatar: "", customProfileMsg: "", customProfileAvatar: "", specificCustomLastPost: {}, specificCustomQuote: {}, specificCustomPost: {}, specificCustomProfileMsg: {} }; if (!settings.specificCustomLastPost) settings.specificCustomLastPost = {}; if (!settings.specificCustomQuote) settings.specificCustomQuote = {}; if (!settings.specificCustomPost) settings.specificCustomPost = {}; if (!settings.specificCustomProfileMsg) settings.specificCustomProfileMsg = {}; } function saveSetting(key, value) { if (typeof key === "object") { settings[key.key][key.subkey] = value; } else { settings[key] = value; } localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings)); } function AddBlacklistLink() { //wip } //functions called by the routers function handlePosts() { loadBlackList(); loadSettings(); addPostsBlackListButtons(); switch (settings.postMode) { case IGNORE: ignorePosts(); return; case REPLACE: replacePosts(); break; case DO_NOTHING: break; default: saveSetting("postMode", REPLACE); replacePosts(); break; } if (settings.replaceAvatar) replaceAvatar(); if (settings.removeSignatures) removeSignatures(); if (settings.removeUserinfo) removeUserinfo(); if (settings.replaceUsername) replaceUsername(); } function handleLastPost() { loadBlackList(); loadSettings(); switch (settings.lastpostMode) { case IGNORE: ignoreLastPost(); return; case REPLACE: replaceLastPost(); break; case DO_NOTHING: break; default: saveSetting("lastpostMode", IGNORE); ignoreLastPost(); break; } } function handleQuotes() { loadBlackList(); loadSettings(); switch (settings.quoteMode) { case IGNORE: ignoreQuotes(); return; case REPLACE: replaceQuotes(); break; case DO_NOTHING: break; default: saveSetting("quoteMode", IGNORE); ignoreQuotes(); break; } } function handleTopics() { loadBlackList(); loadSettings(); if (settings.removeTopics) { ignoreTopics(); } } function handleProfileMsgs() { loadBlackList(); loadSettings(); addProfileMsgBlackListButtons(); switch (settings.profileMsgMode) { case IGNORE: ignoreProfileMsgs(); return; case REPLACE: replaceProfileMsg(); break; case DO_NOTHING: break; default: saveSetting("profileMsgMode", IGNORE); ignoreProfileMsgs(); break; } if (settings.replaceProfileAvatar) replaceProfileAvatar(); } function handleComToCom() { loadBlackList(); loadSettings(); addComToComBlackListButtons(); switch (settings.profileMsgMode) { case IGNORE: ignoreComToCom(); return; case REPLACE: replaceComToCom(); break; case DO_NOTHING: break; default: saveSetting("profileMsgMode", IGNORE); ignoreComToCom(); break; } if (settings.replaceProfileAvatar) replaceComToComAvatar(); } function handleBlacklist() { loadBlackList(); loadSettings(); document.title = "Blacklist - MyAnimeList.net"; //remove the 404 stuff document.querySelector("h1").textContent = "Ignore List"; document.querySelector(".error404").remove(); //CSS addStyle(".flex{display:flex;gap:20px;margin-top:10px;}.user{display:flex;margin:10px}.name{margin-right:20px}.name{border-bottom:solid #000 1px}.name[contenteditable]{min-width:100px;border-bottom:solid #000 1px}.name[contenteditable]:focus{border:none;outline:solid red 5px}.page-common #content{display:flex;justify-content:center;}.settings{display:flex;gap:25px;}.settings>*{padding: 25px;}.customPost{width:100% !important;}.select-users{font-size:1rem;padding:10px;font-weight:bold;}"); //HTML for the blacklist document.getElementById("content").innerHTML = `<div data-blacklist class="black-list"></div> <div data-add-user class="add-user"> <div data-user class="user"> <div data-name class="name" contenteditable="true" onclick="this.focus()"></div> <button data-add class="add">Add</div> </div> </div>` //HTML for the settings const settings = document.createElement("div"); settings.innerHTML = ` <h2>Settings</h2> <form> <div class="settings"> <div class="posts"> <h3>Posts</h3> <div class="form-check"> <input class="form-check-input" type="radio" name="posts" id="doNothingPosts" data-clickable-setting="doNothingPosts"> <label class="form-check-label" for="doNothingPosts"> Do nothing </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="posts" id="hidePosts" data-clickable-setting="hidePosts"> <label class="form-check-label" for="hidePosts"> Hide posts </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="posts" id="replacePosts" data-clickable-setting="replacePosts"> <label class="form-check-label" for="replacePosts"> Replace posts with a custom message </label> </div> <textarea class="form-control customPost" name="customPost" id="customPost" data-text-setting="customPost"></textarea> </div> <div class="posts-extra"> <h3>Posts extra options</h3> <div class="form-check"> <input class="form-check-input" type="checkbox" name="replaceUsername" id="replaceUsername" data-clickable-setting="replaceUsername"> <label class="form-check-label" for="replaceUsername"> Replace user name with a custom name </label> <input class="form-control" type="text" name="customUsername" id="customUsername" data-text-setting="customUsername" placeholder="removed-user"> <br> <small>Leave it empty to remove the username</small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" name="replaceAvatar" id="replaceAvatar" data-clickable-setting="replaceAvatar"> <label class="form-check-label" for="replaceAvatar"> Replace avatars with a custom avatar </label> <input class="form-control" type="text" name="customAvatar" id="customAvatar" data-text-setting="customAvatar"> <br> <small>Leave it empty to remove the avatar</small> </div> <div class="form-check" style="margin-top: 10px;"> <input class="form-check-input" type="checkbox" name="removeSignatures" id="removeSignatures" data-clickable-setting="removeSignatures"> <label class="form-check-label" for="removeSignatures"> Hide the signature </label> </div> <div class="form-check" style="margin-top: 10px;"> <input class="form-check-input" type="checkbox" name="removeUserinfo" id="removeUserinfo" data-clickable-setting="removeUserinfo"> <label class="form-check-label" for="removeUserinfo"> Hide user info </label> </div> <small style="margin-top: 20px; display: block;"><strong>These settings have no effect if the Posts setting is set to "Hide Posts"</strong></small> </div> <div class="quotes"> <h3>Quotes</h3> <div class="form-check"> <input class="form-check-input" type="radio" name="quotes" id="doNothingQuotes" data-clickable-setting="doNothingQuotes"> <label class="form-check-label" for="doNothingQuotes"> Do nothing </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="quotes" id="hideQuotes" data-clickable-setting="hideQuotes"> <label class="form-check-label" for="hideQuotes"> Hide quotes </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="quotes" id="replaceQuotes" data-clickable-setting="replaceQuotes"> <label class="form-check-label" for="replaceQuotes"> Replace quotes with a custom message </label> </div> <textarea class="form-control customPost" name="customQuote" id="customQuote" data-text-setting="customQuote"></textarea> </div> <div class="topics"> <h3>Topics</h3> <div class="form-check"> <input class="form-check-input" type="checkbox" name="removeTopics" id="removeTopics" data-clickable-setting="removeTopics"> <label class="form-check-label" for="removeTopics"> Hide topics </label> </div> </div> <div class="unblacklist"> <h3>UnBlacklist</h3> <div class="form-check"> <input class="form-check-input" type="checkbox" name="UnBlacklistUsername" id="UnBlacklistUsername" data-clickable-setting="UnBlacklistUsername"> <label class="form-check-label" for="UnBlacklistUsername"> Show user name when hovering<br>on UnBlacklist buttons/links </label> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" name="removeUnBlacklist" id="removeUnBlacklist" data-clickable-setting="removeUnBlacklist"> <label class="form-check-label" for="removeUnBlacklist"> Hide UnBlacklist buttons/links </label> </div> <small style="margin-top: 20px; display: block;"><strong>These settings have no effect if the Posts setting<br>is set to "Hide Posts" or Profile Messages setting<br>is set to "Hide profile messages"</strong></small> </div> </div> <div class="settings"> <div class="profile-messages"> <h3>Profile messages</h3> <div class="form-check"> <input class="form-check-input" type="radio" name="profileMsgs" id="doNothingProfileMsgs" data-clickable-setting="doNothingProfileMsgs"> <label class="form-check-label" for="doNothingProfileMsgs"> Do nothing </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="profileMsgs" id="hideProfileMsgs" data-clickable-setting="hideProfileMsgs"> <label class="form-check-label" for="hideProfileMsgs"> Hide profile messages </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="profileMsgs" id="replaceProfileMsgs" data-clickable-setting="replaceProfileMsgs"> <label class="form-check-label" for="replaceProfileMsgs"> Replace profile messages with a custom message </label> </div> <textarea class="form-control customPost" name="customProfileMsg" id="customProfileMsg" data-text-setting="customProfileMsg"></textarea> </div> <div class="profile-messages-extra"> <h3>Profile messages extra options</h3> <div class="form-check"> <input class="form-check-input" type="checkbox" name="replaceProfileUsername" id="replaceProfileUsername" data-clickable-setting="replaceProfileUsername"> <label class="form-check-label" for="replaceProfileUsername"> Replace profile user with a custom name </label> <input class="form-control" type="text" name="customProfileUsername" id="customProfileUsername" data-text-setting="customProfileUsername" placeholder="removed-user"> <br> <small>Leave it empty to remove the avatar</small> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" name="replaceProfileAvatar" id="replaceProfileAvatar" data-clickable-setting="replaceProfileAvatar"> <label class="form-check-label" for="replaceProfileAvatar"> Replace profile message avatar with a custom avatar </label> <input class="form-control" type="text" name="customProfileAvatar" id="customProfileAvatar" data-text-setting="customProfileAvatar"> <br> <small>Leave it empty to remove the avatar</small> </div> <small style="margin-top: 20px; display: block;"><strong>These settings have no effect if the Profile Messages setting is set to "Hide profile messages"</strong></small> </div> <div class="lastpost"> <h3>Last Post</h3> <div class="form-check"> <input class="form-check-input" type="radio" name="lastpost" id="doNothingLastPost" data-clickable-setting="doNothingLastPost"> <label class="form-check-label" for="doNothingLastPost"> Do nothing </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="lastpost" id="hideLastPost" data-clickable-setting="hideLastPost"> <label class="form-check-label" for="hideLastPost"> Hide last posts </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="lastpost" id="replaceLastPost" data-clickable-setting="replaceLastPost"> <label class="form-check-label" for="replaceLastPost"> Replace user of last posts with a custom message </label> </div> <textarea class="form-control customPost" name="customLastPost" id="customLastPost" data-text-setting="customLastPost" placeholder="type a user name like removed-user"></textarea> </div> </div> <select name="users" class="select-users" data-select-users></select> <div class="flex"> <div class="form-check"> <label class="form-check-label" for="specificCustomPost"> Replace this user's posts with a specific custom message </label> <textarea class="form-control customPost" name="specificCustomPost" id="specificCustomPost" data-text-setting="specificCustomPost"></textarea> </div> <div class="form-check"> <label class="form-check-label" for="specificCustomLastPost"> Replace the last posts username with a specific custom message </label> <textarea class="form-control customPost" name="specificCustomLastPost" id="specificCustomLastPost" data-text-setting="specificCustomLastPost" placeholder="type a user name like removed-user"></textarea> </div> <div class="form-check"> <label class="form-check-label" for="specificCustomProfileMsg"> Replace this user's profile messages with a custom message </label> <textarea class="form-control customPost" name="specificCustomProfileMsg" id="specificCustomProfileMsg" data-text-setting="specificCustomProfileMsg"></textarea> </div> <div class="form-check"> <label class="form-check-label" for="specificCustomQuote"> Replace this user's quotes with a specific custom message </label> <textarea class="form-control customPost" name="specificCustomQuote" id="specificCustomQuote" data-text-setting="specificCustomQuote"></textarea> </div> </div> </form>`; document.getElementById("content").insertAdjacentElement("afterend", settings); startEventListeners(); loadSettingsIntoInputs(); } function clickedSetting(e) { const input = e.target; switch (input.dataset.clickableSetting) { case "doNothingLastPost": saveSetting("lastpostMode", DO_NOTHING); break; case "hideLastPost": saveSetting("lastpostMode", IGNORE); break; case "replaceLastPost": saveSetting("lastpostMode", REPLACE); break; case "doNothingQuotes": saveSetting("quoteMode", DO_NOTHING); break; case "hideQuotes": saveSetting("quoteMode", IGNORE); break; case "replaceQuotes": saveSetting("quoteMode", REPLACE); break; case "doNothingPosts": saveSetting("postMode", DO_NOTHING); break; case "hidePosts": saveSetting("postMode", IGNORE); break; case "replacePosts": saveSetting("postMode", REPLACE); break; case "replaceUsername": saveSetting("replaceUsername", input.checked); break; case "replaceAvatar": saveSetting("replaceAvatar", input.checked); break; case "removeTopics": saveSetting("removeTopics", input.checked); break; case "UnBlacklistUsername": saveSetting("UnBlacklistUsername", input.checked); break; case "removeUnBlacklist": saveSetting("removeUnBlacklist", input.checked); break; case "removeSignatures": saveSetting("removeSignatures", input.checked); break; case "removeUserinfo": saveSetting("removeUserinfo", input.checked); break; case "doNothingProfileMsgs": saveSetting("profileMsgMode", DO_NOTHING); break; case "hideProfileMsgs": saveSetting("profileMsgMode", IGNORE); break; case "replaceProfileMsgs": saveSetting("profileMsgMode", REPLACE); break; case "replaceProfileAvatar": saveSetting("replaceProfileAvatar", input.checked); break; default: return; } } function textSetting(e) { const input = e.target; switch (input.dataset.textSetting) { case "customLastPost": saveSetting("customLastPost", input.value); break; case "customQuote": saveSetting("customQuote", input.value); break; case "customPost": saveSetting("customPost", input.value); break; case "customUsername": saveSetting("customUsername", input.value); break; case "customAvatar": saveSetting("customAvatar", input.value); break; case "customProfileMsg": saveSetting("customProfileMsg", input.value); break; case "customProfileAvatar": saveSetting("customProfileAvatar", input.value); break; case "specificCustomProfileMsg": { const selectedUser = document.querySelector("[data-select-users]").value; saveSetting({ key: "specificCustomProfileMsg", subkey: selectedUser }, input.value); break; } case "specificCustomPost": { const selectedUser = document.querySelector("[data-select-users]").value; saveSetting({ key: "specificCustomPost", subkey: selectedUser }, input.value); break; } case "specificCustomQuote": { const selectedUser = document.querySelector("[data-select-users]").value; saveSetting({ key: "specificCustomQuote", subkey: selectedUser }, input.value); break; } case "specificCustomLastPost": { const selectedUser = document.querySelector("[data-select-users]").value; saveSetting({ key: "specificCustomLastPost", subkey: selectedUser }, input.value); break; } default: return; } } function startEventListeners() { document.querySelector("[data-add]").addEventListener("click", addNode); document.querySelectorAll("[data-clickable-setting]").forEach(clickable => { clickable.addEventListener("click", clickedSetting); }); document.querySelectorAll("[data-text-setting]").forEach(text => { text.addEventListener("input", textSetting); }); document.querySelector("[data-select-users]").addEventListener("change", loadSpecificMessages) blacklist.forEach(createNode); blacklist.forEach(addUserToSelect); } function loadSettingsIntoInputs() { switch (settings.lastpostMode) { case DO_NOTHING: document.getElementById("doNothingLastPost").checked = true; break; case IGNORE: document.getElementById("hideLastPost").checked = true; break; case REPLACE: document.getElementById("replaceLastPost").checked = true; break; default: document.getElementById("hidePosts").checked = true; saveSetting("lastpostMode", IGNORE); break; } switch (settings.quoteMode) { case DO_NOTHING: document.getElementById("doNothingQuotes").checked = true; break; case IGNORE: document.getElementById("hideQuotes").checked = true; break; case REPLACE: document.getElementById("replaceQuotes").checked = true; break; default: document.getElementById("hideQuotes").checked = true; saveSetting("quoteMode", IGNORE); break; } switch (settings.postMode) { case DO_NOTHING: document.getElementById("doNothingPosts").checked = true; break; case IGNORE: document.getElementById("hidePosts").checked = true; break; case REPLACE: document.getElementById("replacePosts").checked = true; break; default: document.getElementById("hidePosts").checked = true; saveSetting("postMode", IGNORE); break; } switch (settings.profileMsgMode) { case DO_NOTHING: document.getElementById("doNothingProfileMsgs").checked = true; break; case IGNORE: document.getElementById("hideProfileMsgs").checked = true; break; case REPLACE: document.getElementById("replaceProfileMsgs").checked = true; break; default: document.getElementById("hideProfileMsgs").checked = true; saveSetting("profileMsgMode", IGNORE); break; } if (settings.removeTopics) { document.getElementById("removeTopics").checked = true; } if (settings.UnBlacklistUsername) { document.getElementById("UnBlacklistUsername").checked = true; } if (settings.removeUnBlacklist) { document.getElementById("removeUnBlacklist").checked = true; } if (settings.removeSignatures) { document.getElementById("removeSignatures").checked = true; } if (settings.removeUserinfo) { document.getElementById("removeUserinfo").checked = true; } if (settings.replaceUsername) { document.getElementById("replaceUsername").checked = true; } if (settings.replaceAvatar) { document.getElementById("replaceAvatar").checked = true; } if (settings.replaceProfileAvatar) { document.getElementById("replaceProfileAvatar").checked = true; } document.getElementById("customLastPost").value = settings.customLastPost || ""; document.getElementById("customQuote").value = settings.customQuote || ""; document.getElementById("customPost").value = settings.customPost || ""; document.getElementById("customUsername").value = settings.customUsername || ""; document.getElementById("customAvatar").value = settings.customAvatar || ""; document.getElementById("customProfileMsg").value = settings.customProfileMsg || ""; document.getElementById("customProfileAvatar").value = settings.customProfileAvatar || ""; document.querySelector("[data-select-users]").dispatchEvent(new Event("change")); } function alterLastPost(action) { document.querySelectorAll(QUOTE_SELECTOR).forEach(quotes => { if (quotes.querySelector(FORUM_QUOTE_NAME_SELECTOR) == null) return; const quoteuser = quotes.querySelector(FORUM_QUOTE_NAME_SELECTOR).textContent; let user = quoteuser.replace(' said:',''); if (!blacklist.includes(user)) return; let quote = quotes; action(quote, user); }); } function alterQuotes(action) { document.querySelectorAll(QUOTE_SELECTOR).forEach(quotes => { if (quotes.querySelector(FORUM_QUOTE_NAME_SELECTOR) == null) return; const quoteuser = quotes.querySelector(FORUM_QUOTE_NAME_SELECTOR).textContent; let user = quoteuser.replace(' said:',''); if (!blacklist.includes(user)) return; let quote = quotes; action(quote, user); }); } function alterPosts(action) { document.querySelectorAll(POST_USERS_SELECTOR).forEach(user => { if (!blacklist.includes(user.querySelector(FORUM_MSG_NAME_SELECTOR).textContent)) return; let post = user.parentNode; //for (let i = 0; i < 4; i++) { //post = post.parentNode; //} action(post, user); }); } function alterProfileMessages(action) { document.querySelectorAll(PROFILE_MSG_SELECTOR).forEach(profileMessage => { const username = profileMessage.querySelector(PROFILE_MSG_NAME_SELECTOR).textContent; if (!blacklist.includes(username)) return; action(profileMessage, username); }); } function alterComToCom(action) { document.querySelectorAll(COMTOCOM_SELECTOR).forEach(comMessage => { const username = comMessage.querySelector(COMTOCOM_NAME_SELECTOR).textContent; if (!blacklist.includes(username)) return; action(comMessage, username); }); } function ignoreLastPost() { alterQuotes(quote => { quote.style.display = "none"; //post.previousElementSibling.style.display = "none"; }); } function replaceLastPost() { alterQuotes((quote, user) => { const specificCustomLastPost = settings.specificCustomLastPost[user]; quote.innerHTML = specificCustomLastPost ? specificCustomLastPost : settings.customQuote; }); } function ignoreQuotes() { alterQuotes(quote => { quote.style.display = "none"; //post.previousElementSibling.style.display = "none"; }); } function replaceQuotes() { alterQuotes((quote, user) => { const specificCustomQuote = settings.specificCustomQuote[user]; quote.innerHTML = specificCustomQuote ? specificCustomQuote : settings.customQuote; }); } function ignorePosts() { alterPosts(post => { post.style.display = "none"; post.previousElementSibling.style.display = "none"; }); } function replacePosts() { alterPosts((post, user) => { const username = user.querySelector(FORUM_MSG_NAME_SELECTOR).textContent; const specificCustomPost = settings.specificCustomPost[username]; post.querySelector(MESSAGE_SELECTOR).innerHTML = specificCustomPost ? specificCustomPost : settings.customPost; }); } function replaceProfileMsg() { alterProfileMessages((profileMessage, username) => { const specificCustomProfileMsg = settings.specificCustomProfileMsg[username]; profileMessage.querySelector(PROFILE_MSG_TEXT_SELECTOR).innerHTML = specificCustomProfileMsg ? specificCustomProfileMsg : settings.customProfileMsg; }); } function replaceComToCom() { alterComToCom((comMessage, username) => { const specificCustomProfileMsg = settings.specificCustomProfileMsg[username]; comMessage.querySelector(COMTOCOM_TEXT_SELECTOR).innerHTML = specificCustomProfileMsg ? specificCustomProfileMsg : settings.customProfileMsg; }); } function ignoreTopics() { document.querySelectorAll(TOPIC_USERS_SELECTOR).forEach(user => { if (!blacklist.includes(user.textContent)) return; user.closest("tr").style.display = "none"; }); } function ignoreProfileMsgs() { alterProfileMessages(profileMessage => { profileMessage.style.display = "none"; }); } function ignoreComToCom() { alterComToCom(comMessage => { comMessage.style.display = "none"; }); } function replaceUsername() { alterPosts((post, user) => { user.querySelector(FORUM_MSG_NAME_SELECTOR).innerHTML = `<a href="${user.querySelector(USER_PROFILE_SELECTOR).href}">${settings.customUsername}</a>`; }); } function replaceAvatar() { alterPosts((post, user) => { const avatar = user.querySelector(AVATAR_SELECTOR); if (!avatar) { if (settings.customAvatar === "") return; const avatar = document.createElement("a"); avatar.href = user.querySelector(USER_PROFILE_SELECTOR).href; avatar.className = "forum-icon"; avatar.innerHTML = ` <img class=" lazyloaded" data-src="${settings.customAvatar}" vspace="2" border="0" src="${settings.customAvatar}" width="100" height="125">`; user.querySelector(USER_INFO_SELECTOR).insertAdjacentElement('afterend', avatar); } else { if (settings.customAvatar === "") { avatar.style.display = "none"; return; } const img = avatar.querySelector("img"); img.src = settings.customAvatar; img.setAttribute("data-src", settings.customAvatar); img.setAttribute("width", 100); img.setAttribute("height", 125); } }); } function replaceProfileAvatar() { alterProfileMessages(profileMessage => { const avatar = profileMessage.querySelector(PROFILE_MSG_AVATAR_SELECTOR); if (settings.customProfileAvatar === "") { avatar.style.display = "none"; return; } const img = avatar.querySelector("img"); img.src = settings.customProfileAvatar; img.setAttribute("data-src", settings.customProfileAvatar); }); } function replaceComToComAvatar() { alterComToCom(comMessage => { const avatar = comMessage.querySelector(COMTOCOM_AVATAR_SELECTOR); if (settings.customProfileAvatar === "") { avatar.style.display = "none"; return; } const img = avatar.querySelector("img"); img.src = settings.customProfileAvatar; img.setAttribute("data-src", settings.customProfileAvatar); }); } function removeSignatures() { alterPosts(post => { const signature = post.querySelector(SIGNATURE_SELECTOR); if (!signature) return; signature.style.display = "none"; }); } function removeUserinfo() { alterPosts(post => { const userinfo = post.querySelector(USERINFO_SELECTOR); if (!userinfo) return; userinfo.style.display = "none"; const userinfo1 = post.querySelector(USERINFO_SELECTOR1); if (!userinfo1) return; userinfo1.style.display = "none"; const userinfo2 = post.querySelector(USERINFO_SELECTOR2); if (!userinfo2) return; userinfo2.style.display = "none"; const userinfo3 = post.querySelector(USERINFO_SELECTOR3); if (!userinfo3) return; userinfo3.style.display = "none"; const userinfo4 = post.querySelector(USERINFO_SELECTOR4); if (userinfo4) { userinfo4.style.display = "none"; } const userinfo5 = post.querySelector(USERINFO_SELECTOR5); if (userinfo5) { userinfo5.style.display = "none"; } const userinfo6 = post.querySelector(USERINFO_SELECTOR6); if (userinfo6) { userinfo6.style.display = "none"; } }); } function addPostsBlackListButtons() { document.querySelectorAll(FORUM_MESSAGE_SELECTOR).forEach(forumMessage => { const actionBar = forumMessage.querySelector(FORUM_ACTION_BAR_SELECTOR); const username = forumMessage.querySelector(FORUM_MSG_NAME_SELECTOR).textContent; if (!blacklist.includes(username)) { addBlackListButton(actionBar, username); } else { addUnBlackListButton(actionBar, username); } }); } function addProfileMsgBlackListButtons() { document.querySelectorAll(PROFILE_MSG_SELECTOR).forEach(profileMessage => { let actionBar = profileMessage.querySelector(PROFILE_MSG_ACTION_BAR_SELECTOR); const username = profileMessage.querySelector(PROFILE_MSG_NAME_SELECTOR).textContent; //this happens when you are looking at someone elses profile, create the actionBar. if (!actionBar) { actionBar = document.createElement("div"); actionBar.className = "postActions ar mt4"; profileMessage.querySelector(PROFILE_MSG_TEXT_SELECTOR).insertAdjacentElement("afterend", actionBar); } if (!blacklist.includes(username)) { addBlackListLink(actionBar, username, " | "); } else { addUnBlackListLink(actionBar, username, " | "); } }); } function addComToComBlackListButtons() { document.querySelectorAll(COMTOCOM_SELECTOR).forEach(comMessage => { let actionBar = comMessage.querySelector(COMTOCOM_ACTION_BAR_SELECTOR); const username = comMessage.querySelector(COMTOCOM_NAME_SELECTOR).textContent; //this happens when you manually enter the url of com-to-com between 2 users other than you. if (!actionBar) { const actionBarContainer = document.createElement("div"); actionBarContainer.style.marginTop = "10px"; actionBar = document.createElement("small"); actionBarContainer.appendChild(actionBar); comMessage.querySelector(COMTOCOM_TEXT_SELECTOR).insertAdjacentElement("afterend", actionBarContainer); } if (!blacklist.includes(username)) { addBlackListLink(actionBar, username, " | "); } else { addUnBlackListLink(actionBar, username, " | "); } }); } function addBlackListLink(actionBar, username, separator) { const you = document.querySelector(YOU_SELECTOR).textContent; if (username == you) return const a = document.createElement("a"); a.href = "javascript:void(0)"; a.textContent = "Blacklist User"; a.dataset.username = username; a.onclick = blacklistUser; actionBar.after(a); if (separator) { actionBar.after(document.createTextNode(separator)); } } function addUnBlackListLink(actionBar, username, separator) { if (settings.removeUnBlacklist) return; const a = document.createElement("a"); a.href = "javascript:void(0)"; a.textContent = "UnBlacklist User"; if (settings.UnBlacklistUsername) a.title = username; a.dataset.username = username; a.onclick = blacklistUser; actionBar.after(a); if (separator) { actionBar.after(document.createTextNode(separator)); } } function addBlackListButton(actionBar, username, separator) { const you = document.querySelector(YOU_SELECTOR).textContent; if (username == you) return const a = document.createElement("button"); a.href = "javascript:void(0)"; a.textContent = "Blacklist User"; a.classList.add("mal-btn"); a.classList.add("secondary"); a.classList.add("small"); a.classList.add("outline"); a.classList.add("noborder"); a.dataset.username = username; a.onclick = blacklistUser; if (actionBar.childElementCount > 0 && separator) { actionBar.prepend(document.createTextNode(separator)); } actionBar.prepend(a); } function addUnBlackListButton(actionBar, username, separator) { if (settings.removeUnBlacklist) return; const a = document.createElement("button"); a.href = "javascript:void(0)"; a.textContent = "UnBlacklist User"; a.classList.add("mal-btn"); a.classList.add("secondary"); a.classList.add("small"); a.classList.add("outline"); a.classList.add("noborder"); if (settings.UnBlacklistUsername) a.title = username; a.dataset.username = username; a.onclick = blacklistUser; if (actionBar.childElementCount > 0 && separator) { actionBar.prepend(document.createTextNode(separator)); } actionBar.prepend(a); } function blacklistUser(e) { const username = e.target.dataset.username; if (blacklist.includes(username)) { removeUser(username); window.location.reload(); } else { addUser(username); window.location.reload(); } } //Add a user to the blacklist function addUser(username) { blacklist.push(username); saveBlackList(); } //Remove a user from the blacklist if it's there function removeUser(userName) { blacklist = blacklist.filter(name => userName !== name); saveBlackList(); } //remove the user node from the html code and then update the localStorage function removeNode(e) { const row = e.target.parentNode; const name = row.querySelector("[data-name]").textContent; row.remove(); removeUser(name); removeUserFromSelect(name); } //modify the user node from the html code and then update the localStorage function saveNode(e) { const newName = e.target.textContent; const previousName = e.target.dataset.previousName; previousName && removeUser(previousName); if (newName !== "") { addUser(newName); e.target.dataset.previousName = newName; } else { e.target.parentNode.remove(); } } //add a new user node to the html code and then update the localStorage function addNode(e) { const node = e.target.parentNode; const usernameNode = node.querySelector("[data-name]"); const username = usernameNode.textContent; usernameNode.textContent = ""; if (!blacklist.includes(username)) { createNode(username); addUser(username); addUserToSelect(username); } } //create the user node then add it to the html code function createNode(username) { const newUser = document.createElement("div"); newUser.setAttribute("data-user", ""); newUser.className = "user"; newUser.innerHTML = `<div data-name class="name" contenteditable="true" onclick="this.focus()" data-previous-name="${username}">${username}</div> <button data-remove class="remove">Remove</button>`; newUser.querySelector("[data-name]").addEventListener("focusout", saveNode); newUser.querySelector("[data-remove]").addEventListener("click", removeNode); document.querySelector("[data-blacklist]").append(newUser); } //add the users inside the user select element function addUserToSelect(username) { const selectUser = document.querySelector("[data-select-users]"); const option = document.createElement("option"); option.value = option.textContent = username; selectUser.appendChild(option); } //remove the user from the select list function removeUserFromSelect(username) { const userOption = document.querySelector(`[data-select-users] [value="${username}"]`); if (userOption) userOption.remove(); } //load a custom post and custom profile message of a specific blacklisted user into the 2 text areas designated for these inputs function loadSpecificMessages(e) { const userCustomLastPost = settings.specificCustomLastPost[e.target.value]; const userCustomQuote = settings.specificCustomQuote[e.target.value]; const userCustomPost = settings.specificCustomPost[e.target.value]; const userCustomProfileMsg = settings.specificCustomProfileMsg[e.target.value]; const customLastPost = document.getElementById("specificCustomLastPost"); const customQuote = document.getElementById("specificCustomQuote"); const customPost = document.getElementById("specificCustomPost"); const customProfileMsg = document.getElementById("specificCustomProfileMsg"); customLastPost.value = userCustomLastPost ? userCustomLastPost : ""; customQuote.value = userCustomQuote ? userCustomQuote : ""; customPost.value = userCustomPost ? userCustomPost : ""; customProfileMsg.value = userCustomProfileMsg ? userCustomProfileMsg : ""; } })();