您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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.89
- // @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
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_registerMenuCommand
- // ==/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 LAST_POST_LIST_CONTAINER_SELECTOR = "li.clearfix";
- const LAST_POST_LIST_USER_SELECTOR = "span.date a[href*='/profile/']";
- const LAST_POST_LIST_AVATAR_SELECTOR = LAST_POST_LIST_CONTAINER_SELECTOR + " > a[href*='/profile/']";
- const LAST_POST_TABLE_CONTAINER_SELECTOR = "td.forum_boardrow1[align='right'][width='130']";
- const LAST_POST_TABLE_USER_SELECTOR = "a[href*='/profile/']";
- const FORUM_QUOTE_NAME_SELECTOR = ".quotetext > strong > a";
- const FORUM_REPLY_NAME_SELECTOR = ".js-replyto-target";
- const REPLIED_CONTAINER_SELECTOR = ".replied.show";
- 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;
- const MIGRATION_COMPLETE_KEY = 'ignore-list-migration-complete';
- const defaultSettings = {
- replaceUsername: false,
- replaceAvatar: true,
- replaceProfileAvatar: false,
- removeSignatures: true,
- removeUserinfo: true,
- lastpostMode: REPLACE,
- quoteMode: IGNORE,
- replyMode: IGNORE,
- postMode: REPLACE,
- profileMsgMode: IGNORE,
- removeTopics: true,
- UnBlacklistUsername: false,
- removeUnBlacklist: false,
- customLastPost: "removed-user",
- customQuote: "",
- customReply: "",
- customPost: "",
- customAvatar: "",
- customProfileMsg: "",
- customProfileAvatar: "",
- specificCustomLastPost: {},
- specificCustomQuote: {},
- specificCustomReply: {},
- specificCustomPost: {},
- specificCustomProfileMsg: {}
- };
- GM_registerMenuCommand("Backup Settings to localStorage", backupToLocalStorage);
- //routing
- if (window.location.href.includes(FORUM_OPTIONS)) {
- AddBlacklistLink();
- } else if (window.location.href.includes(POSTS_URL)) {
- handlePosts();
- handleQuotes();
- handleReplies();
- } 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();
- handleLastPost();
- } 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();
- if (settings.replaceAvatar) replaceAvatar();
- }
- //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;
- }
- // --- Function to create a temporary message box ---
- function showTemporaryMessage(message, duration = 3000) {
- // Remove any existing message boxes first
- const existingMessageBox = document.getElementById('gm_backup_message');
- if (existingMessageBox) {
- existingMessageBox.remove();
- }
- // Create the message box element
- const messageBox = document.createElement('div');
- messageBox.id = 'gm_backup_message';
- messageBox.textContent = message;
- messageBox.style.cssText = `
- position: fixed;
- top: 20px;
- left: 50%;
- transform: translateX(-50%);
- padding: 10px 20px;
- background-color: #4CAF50; /* Green background */
- color: white;
- border-radius: 5px;
- z-index: 10000; /* High z-index to be on top */
- opacity: 0.9;
- font-family: sans-serif;
- font-size: 14px;
- box-shadow: 0 2px 5px rgba(0,0,0,0.2);
- `;
- // Append to the body
- document.body.appendChild(messageBox);
- // Remove the message box after the specified duration
- setTimeout(() => {
- messageBox.remove();
- }, duration);
- }
- // --- Function to perform the backup to localStorage ---
- function backupToLocalStorage() {
- try {
- // Retrieve the current data from GM_setValue
- // Use the default values in case GM_getValue returns null, although
- // if your script is running, settings/blacklist should be populated.
- // Retrieving directly from GM_getValue ensures we get the saved state,
- // not just the current in-memory state if it hasn't been saved yet.
- const currentSettingsJson = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- const currentBlacklistJson = GM_getValue(BLACKLIST_KEY, '[]');
- // Save the data to localStorage
- localStorage.setItem(SETTINGS_KEY, currentSettingsJson);
- localStorage.setItem(BLACKLIST_KEY, currentBlacklistJson);
- console.log('Settings and Blacklist backed up to localStorage.');
- showTemporaryMessage('Backup to localStorage complete!');
- } catch (e) {
- console.error('Error during backup to localStorage:', e);
- showTemporaryMessage('Backup failed!', 5000); // Show error message longer
- }
- }
- // loadBlackList function now handles migration for BOTH blacklist and settings
- function loadBlackList() {
- const isMigrationComplete = GM_getValue(MIGRATION_COMPLETE_KEY, false);
- let loadedBlacklist; // Temporary variable for blacklist data
- let loadedSettings; // Temporary variable for settings data
- if (!isMigrationComplete) {
- // Migration not complete, check localStorage for BOTH keys
- const localStorageBlacklist = localStorage.getItem(BLACKLIST_KEY);
- const localStorageSettings = localStorage.getItem(SETTINGS_KEY);
- if (localStorageBlacklist !== null || localStorageSettings !== null) {
- // Data found in localStorage for at least one item, attempt migration
- console.log('localStorage data found, attempting migration for both blacklist and settings to GM_setValue...');
- // --- Handle Blacklist Migration ---
- if (localStorageBlacklist !== null) {
- try {
- loadedBlacklist = JSON.parse(localStorageBlacklist);
- // Ensure it's an array before saving
- if (!Array.isArray(loadedBlacklist)) {
- console.warn('localStorage blacklist is not an array, resetting to empty array.');
- loadedBlacklist = [];
- }
- GM_setValue(BLACKLIST_KEY, JSON.stringify(loadedBlacklist));
- console.log('Blacklist migrated from localStorage.');
- } catch (e) {
- console.error('Error parsing localStorage blacklist during migration.', e);
- // On error, load from GM_setValue instead for this run
- const gmBlacklist = GM_getValue(BLACKLIST_KEY, '[]');
- loadedBlacklist = JSON.parse(gmBlacklist);
- console.log('Blacklist loaded from GM_setValue due to localStorage parse error.');
- }
- } else {
- // No blacklist in localStorage, load from GM_setValue
- const gmBlacklist = GM_getValue(BLACKLIST_KEY, '[]');
- loadedBlacklist = JSON.parse(gmBlacklist);
- // Ensure it's an array even if loading from GM failed initially
- if (!Array.isArray(loadedBlacklist)) {
- console.warn('Blacklist loaded from GM_setValue is not an array, resetting to empty array.');
- loadedBlacklist = [];
- }
- console.log('Blacklist not found in localStorage, loaded from GM_setValue.');
- }
- // --- Handle Settings Migration ---
- if (localStorageSettings !== null) {
- try {
- loadedSettings = JSON.parse(localStorageSettings);
- GM_setValue(SETTINGS_KEY, JSON.stringify(loadedSettings));
- console.log('Settings migrated from localStorage.');
- } catch (e) {
- console.error('Error parsing localStorage settings during migration.', e);
- // On error, load from GM_setValue instead for this run
- const gmSettings = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- loadedSettings = JSON.parse(gmSettings);
- console.log('Settings loaded from GM_setValue due to localStorage parse error.');
- }
- } else {
- // No settings in localStorage, load from GM_setValue
- const gmSettings = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- loadedSettings = JSON.parse(gmSettings);
- console.log('Settings not found in localStorage, loaded from GM_setValue.');
- }
- // *** Set the migration complete flag in GM_setValue AFTER attempting both migrations ***
- GM_setValue(MIGRATION_COMPLETE_KEY, true);
- console.log('Migration to GM_setValue marked as complete.');
- } else {
- // No data found in localStorage for either key, perform standard load from GM_setValue
- console.log('No localStorage data found for migration. Loading both from GM_setValue...');
- const gmBlacklist = GM_getValue(BLACKLIST_KEY, '[]');
- loadedBlacklist = JSON.parse(gmBlacklist);
- // Ensure blacklist is an array
- if (!Array.isArray(loadedBlacklist)) {
- console.warn('Blacklist loaded from GM_setValue is not an array, resetting to empty array.');
- loadedBlacklist = [];
- GM_setValue(BLACKLIST_KEY, '[]'); // Save the corrected default
- }
- const gmSettings = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- loadedSettings = JSON.parse(gmSettings);
- }
- } else {
- // Migration is complete, load BOTH directly from GM_setValue
- console.log('Migration complete. Loading blacklist and settings directly from GM_setValue...');
- const gmBlacklist = GM_getValue(BLACKLIST_KEY, '[]');
- loadedBlacklist = JSON.parse(gmBlacklist);
- // Ensure blacklist is an array
- if (!Array.isArray(loadedBlacklist)) {
- console.warn('Blacklist loaded from GM_setValue is not an array, resetting to empty array.');
- loadedBlacklist = [];
- GM_setValue(BLACKLIST_KEY, '[]'); // Save the corrected default
- }
- const gmSettings = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- loadedSettings = JSON.parse(gmSettings);
- }
- // Assign the loaded data to the script's variables after the entire loading process
- blacklist = loadedBlacklist;
- settings = loadedSettings;
- // Ensure nested objects and missing properties exist for settings
- // This handles cases where loaded data might be from an older version or parsed poorly
- let settingsChangedAfterLoad = false;
- if (!settings.specificCustomLastPost) { settings.specificCustomLastPost = {}; settingsChangedAfterLoad = true; }
- if (!settings.specificCustomQuote) { settings.specificCustomQuote = {}; settingsChangedAfterLoad = true; }
- if (!settings.specificCustomReply) { settings.specificCustomReply = {}; settingsChangedAfterLoad = true; }
- if (!settings.specificCustomPost) { settings.specificCustomPost = {}; settingsChangedAfterLoad = true; }
- if (!settings.specificCustomProfileMsg) { settings.specificCustomProfileMsg = {}; settingsChangedAfterLoad = true; }
- for (const key in defaultSettings) {
- if (Object.prototype.hasOwnProperty.call(defaultSettings, key)) {
- if (typeof defaultSettings[key] === 'object' && defaultSettings[key] !== null && !Array.isArray(defaultSettings[key])) {
- continue; // Skip specificCustom objects
- }
- if (settings[key] === undefined) {
- settings[key] = defaultSettings[key];
- settingsChangedAfterLoad = true;
- console.log(`Settings: Added missing key "${key}" with default value after load.`);
- }
- }
- }
- // Save the potentially updated settings back to GM_setValue if defaults were added
- if (settingsChangedAfterLoad) {
- GM_setValue(SETTINGS_KEY, JSON.stringify(settings));
- console.log('Settings updated with missing defaults and saved to GM_setValue.');
- }
- // Note: The migration complete flag is handled earlier in this function.
- // Blacklist is assigned directly above and doesn't need a separate save for defaults
- // unless it failed parsing and was reset to []. That save happens inside the checks.
- }
- // loadSettings function now only loads from GM_setValue
- function loadSettings() {
- // In this revised approach, loadBlackList handles the initial loading
- // and migration for both settings and blacklist on the first run.
- // loadSettings should now assume that initial loading has occurred (or will
- // occur via loadBlackList if loadSettings is somehow called first on a fresh run).
- // It simply loads the current state of settings from GM_setValue.
- console.log('Loading settings from GM_setValue...');
- const gmSettings = GM_getValue(SETTINGS_KEY, JSON.stringify(defaultSettings));
- settings = JSON.parse(gmSettings);
- // Ensure nested objects and missing properties exist for settings
- let settingsChanged = false;
- if (!settings.specificCustomLastPost) { settings.specificCustomLastPost = {}; settingsChanged = true; }
- if (!settings.specificCustomQuote) { settings.specificCustomQuote = {}; settingsChanged = true; }
- if (!settings.specificCustomReply) { settings.specificCustomReply = {}; settingsChanged = true; }
- if (!settings.specificCustomPost) { settings.specificCustomPost = {}; settingsChanged = true; }
- if (!settings.specificCustomProfileMsg) { settings.specificCustomProfileMsg = {}; settingsChanged = true; }
- for (const key in defaultSettings) {
- if (Object.prototype.hasOwnProperty.call(defaultSettings, key)) {
- if (typeof defaultSettings[key] === 'object' && defaultSettings[key] !== null && !Array.isArray(defaultSettings[key])) {
- continue;
- }
- if (settings[key] === undefined) {
- settings[key] = defaultSettings[key];
- settingsChanged = true;
- console.log(`Settings: Added missing key "${key}" with default value.`);
- }
- }
- }
- // Save the potentially updated settings back to GM_setValue if defaults were added
- if (settingsChanged) {
- GM_setValue(SETTINGS_KEY, JSON.stringify(settings));
- console.log('Settings updated with missing defaults and saved to GM_setValue.');
- }
- }
- // saveBlackList remains the same, always saving to GM_setValue
- function saveBlackList() {
- GM_setValue(BLACKLIST_KEY, JSON.stringify(blacklist));
- }
- // saveSetting remains the same, always saving to GM_setValue
- function saveSetting(key, value) {
- // Update the in-memory settings object first
- if (typeof key === "object") {
- if (settings[key.key] && typeof settings[key.key] === 'object') {
- settings[key.key][key.subkey] = value;
- } else {
- console.error(`Attempted to set subkey on non-object settings property: ${key.key}`);
- }
- } else {
- settings[key] = value;
- }
- // Save the entire updated settings object to GM_setValue
- GM_setValue(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 handleReplies() {
- loadBlackList();
- loadSettings();
- switch (settings.replyMode) {
- case IGNORE:
- ignoreReplies();
- return;
- case REPLACE:
- replaceReplies();
- break;
- case DO_NOTHING:
- break;
- default:
- saveSetting("replyMode", IGNORE);
- ignoreReplies();
- 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="replies">
- <h3>Replies</h3>
- <div class="form-check">
- <input class="form-check-input" type="radio" name="replies" id="doNothingReplies" data-clickable-setting="doNothingReplies">
- <label class="form-check-label" for="doNothingReplies">
- Do nothing
- </label>
- </div>
- <div class="form-check">
- <input class="form-check-input" type="radio" name="replies" id="hideReplies" data-clickable-setting="hideReplies">
- <label class="form-check-label" for="hideReplies">
- Hide replies
- </label>
- </div>
- <div class="form-check">
- <input class="form-check-input" type="radio" name="replies" id="replaceReplies" data-clickable-setting="replaceReplies">
- <label class="form-check-label" for="replaceReplies">
- Replace replies with a custom message
- </label>
- </div>
- <textarea class="form-control customPost" name="customReply" id="customReply" data-text-setting="customReply"></textarea>
- </div>
- </div>
- <div class="settings">
- <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 user created topics
- </label>
- </div>
- </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 name with a custom name
- </label>
- <br>
- <input class="form-control" type="text" name="customLastPost" id="customLastPost" data-text-setting="customLastPost" placeholder="removed-user">
- <br>
- <small>Leave it empty to remove the username</small>
- </div>
- </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>
- <br>
- <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>
- <br>
- <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="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>
- <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 class="form-check">
- <label class="form-check-label" for="specificCustomReply">
- Replace this user's replies with a specific custom message
- </label>
- <textarea class="form-control customPost" name="specificCustomReply" id="specificCustomReply" data-text-setting="specificCustomReply"></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 "doNothingReplies":
- saveSetting("replyMode", DO_NOTHING);
- break;
- case "hideReplies":
- saveSetting("replyMode", IGNORE);
- break;
- case "replaceReplies":
- saveSetting("replyMode", 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 "customReply":
- saveSetting("customReply", 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 "specificCustomReply":
- {
- const selectedUser = document.querySelector("[data-select-users]").value;
- saveSetting({ key: "specificCustomReply", 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("hideLastPost").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.replyMode) {
- case DO_NOTHING:
- document.getElementById("doNothingReplies").checked = true;
- break;
- case IGNORE:
- document.getElementById("hideReplies").checked = true;
- break;
- case REPLACE:
- document.getElementById("replaceReplies").checked = true;
- break;
- default:
- document.getElementById("hideReplies").checked = true;
- saveSetting("replyMode", 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("customReply").value = settings.customReply || "";
- 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) {
- const listItems = document.querySelectorAll(LAST_POST_LIST_CONTAINER_SELECTOR);
- const tableCells = document.querySelectorAll(LAST_POST_TABLE_CONTAINER_SELECTOR);
- const allLastPostElements = [...listItems, ...tableCells];
- allLastPostElements.forEach((item, index) => {
- let usernameElement = null;
- let user = null;
- if (item.matches(LAST_POST_LIST_CONTAINER_SELECTOR)) {
- usernameElement = item.querySelector(LAST_POST_LIST_USER_SELECTOR);
- } else if (item.matches(LAST_POST_TABLE_CONTAINER_SELECTOR)) {
- usernameElement = item.querySelector(LAST_POST_TABLE_USER_SELECTOR);
- } else {
- return;
- }
- if (!usernameElement) return;
- user = usernameElement.textContent.trim();
- if (!blacklist.includes(user)) return;
- action(item, user, usernameElement);
- });
- }
- 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 alterReplies(action) {
- document.querySelectorAll(REPLIED_CONTAINER_SELECTOR).forEach(replyContainer => {
- const usernameElement = replyContainer.querySelector(FORUM_REPLY_NAME_SELECTOR);
- if (!usernameElement) return;
- const fullText = usernameElement.textContent;
- const usernameMatch = fullText.match(/^Reply to (.+)/);
- let user = null;
- if (usernameMatch && usernameMatch[1]) {
- user = usernameMatch[1].trim();
- }
- if (!blacklist.includes(user)) return;
- action(replyContainer, 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() {
- alterLastPost(lastPostItem => {
- lastPostItem.style.display = "none";
- });
- }
- function replaceLastPost() {
- alterLastPost((lastPostItem, user, usernameElement) => {
- const specificCustomLastPost = settings.specificCustomLastPost ? settings.specificCustomLastPost[user] : null;
- const replacementHTML = specificCustomLastPost ? specificCustomLastPost : (settings.customLastPost || "");
- const tempDiv = document.createElement('div');
- tempDiv.innerHTML = replacementHTML;
- const fragment = document.createDocumentFragment();
- while (tempDiv.firstChild) {
- fragment.appendChild(tempDiv.firstChild);
- }
- const parent = usernameElement.parentNode;
- if (parent) {
- parent.replaceChild(fragment, usernameElement);
- }
- });
- }
- 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 ignoreReplies() {
- alterReplies(replyContainer => {
- replyContainer.style.display = "none";
- });
- }
- function replaceReplies() {
- alterReplies((replyContainer, user) => {
- const specificCustomReply = settings.specificCustomReply ? settings.specificCustomReply[user] : null;
- replyContainer.innerHTML = specificCustomReply ? specificCustomReply : (settings.customReply || "");
- });
- }
- 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 alterLastPostAvatars(action) {
- document.querySelectorAll(LAST_POST_LIST_AVATAR_SELECTOR).forEach(avatarLink => {
- const userMatch = avatarLink.href.split('/').pop();
- if (userMatch && blacklist.includes(userMatch)) {
- action(avatarLink, userMatch);
- }
- });
- }
- function replaceAvatar() {
- alterPosts((post, userElement) => {
- const avatar = userElement.querySelector(AVATAR_SELECTOR);
- if (!avatar) {
- if (settings.customAvatar === "") return;
- const newAvatarLink = document.createElement("a");
- const profileLinkElement = userElement.querySelector(USER_PROFILE_SELECTOR);
- if (profileLinkElement) {
- newAvatarLink.href = profileLinkElement.href;
- } else {
- newAvatarLink.href = "#";
- }
- newAvatarLink.className = "forum-icon";
- newAvatarLink.innerHTML = `
- <img class=" lazyloaded" data-src="${settings.customAvatar}" vspace="2" border="0" src="${settings.customAvatar}" width="100" height="125">`;
- const userInfoElement = userElement.querySelector(USER_INFO_SELECTOR);
- if (userInfoElement) {
- userInfoElement.insertAdjacentElement('afterend', newAvatarLink);
- } else {
- userElement.appendChild(newAvatarLink);
- }
- } else {
- if (settings.customAvatar === "") {
- avatar.style.display = "none";
- return;
- }
- const img = avatar.querySelector("img");
- if (img) {
- img.src = settings.customAvatar;
- img.setAttribute("data-src", settings.customAvatar);
- img.setAttribute("width", 100);
- img.setAttribute("height", 125);
- }
- }
- });
- alterLastPostAvatars((avatarLink, user) => {
- if (settings.customAvatar === "") {
- avatarLink.style.display = "none";
- return;
- }
- const img = avatarLink.querySelector("img");
- if (img) {
- img.src = settings.customAvatar;
- img.setAttribute("data-src", settings.customAvatar);
- img.setAttribute("width", 20);
- img.setAttribute("height", 25);
- } else {
- if (settings.customAvatar !== "") {
- const replacementImg = document.createElement('img');
- replacementImg.src = settings.customAvatar;
- replacementImg.setAttribute("data-src", settings.customAvatar);
- replacementImg.setAttribute("width", 20);
- replacementImg.setAttribute("height", 25);
- const parent = avatarLink.parentNode;
- if (parent) {
- parent.replaceChild(replacementImg, avatarLink);
- }
- }
- }
- });
- }
- 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 userCustomReply = settings.specificCustomReply[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 customReply = document.getElementById("specificCustomReply");
- const customPost = document.getElementById("specificCustomPost");
- const customProfileMsg = document.getElementById("specificCustomProfileMsg");
- customLastPost.value = userCustomLastPost ? userCustomLastPost : "";
- customQuote.value = userCustomQuote ? userCustomQuote : "";
- customReply.value = userCustomReply ? userCustomReply : "";
- customPost.value = userCustomPost ? userCustomPost : "";
- customProfileMsg.value = userCustomProfileMsg ? userCustomProfileMsg : "";
- }
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址