This script compares anime and manga entries from your userlists with entries from anime detail page and bold similar ones
// ==UserScript== // @name MyAnimeList(MAL) - Anime/Manga Entries Compare // @description This script compares anime and manga entries from your userlists with entries from anime detail page and bold similar ones // @match https://myanimelist.net/anime/* // @match https://myanimelist.net/manga/* // @match https://myanimelist.net/anime.php?* // @match https://myanimelist.net/manga.php?* // @exclude /^https?:\/\/myanimelist\.net\/(anime|manga)\/[^0-9]+/ // @exclude /^https?:\/\/myanimelist\.net\/(anime|manga)\/\d+\/.+\/.+/ // @version 1.2.3 // @author Cpt_mathix // @license GPL-2.0-or-later // @namespace https://greasyfork.org/users/16080 // ==/UserScript== /* jshint esversion: 8 */ // get user var user = document.getElementsByClassName('header-profile-link')[0]; if (user) { user = user.textContent; init(); } else { console.log('Not logged in (Anime/Manga Entries Compare)'); } var allElements; function init() { // get Anime/Manga Entries on current page allElements = document.evaluate( '//*[contains(@class, "anime_detail_related_anime")]//a[@href]', document, null, XPathR###lt.UNORDERED_NODE_SNAPSHOT_TYPE, null); activateScript(); } async function activateScript() { console.log('Running script: Anime/Manga Entries Compare'); let animelist = await tryCachedUserList(user, "anime"); animelist = flatten(animelist, "anime_id"); runScript("anime", animelist); let mangalist = await tryCachedUserList(user, "manga"); mangalist = flatten(mangalist, "manga_id"); runScript("manga", mangalist); } function runScript(type, list) { var linkEl, href, self; if (type === "anime") { for (var i = 0; i < allElements.snapshotLength; i++){ linkEl= allElements.snapshotItem(i); href = linkEl.href; // compare Anime Entries with your list if (/http.*:\/\/myanimelist\.net\/anime\/\d+/.test(href)) { var animeid = href.match(/\d+/g)[0]; self = animeid.search(document.location.href.match(/\d+/g)[0]); if (self == -1 && haveListHit(list, animeid)) { linkEl.style.fontWeight="bold"; } } } } else if (type === "manga") { for (var j = 0; j < allElements.snapshotLength; j++){ linkEl= allElements.snapshotItem(j); href = linkEl.href; // compare Manga Entries with your list if (/http.*:\/\/myanimelist\.net\/manga\/\d+/.test(href)) { var mangaid = href.match(/\d+/g)[0]; self = mangaid.search(document.location.href.match(/\d+/g)[0]); if (self == -1 && haveListHit(list, mangaid)) { linkEl.style.fontWeight= "bold"; } } } } } function haveListHit(list, id) { return list[id]; } function flatten(list, id) { let map = {}; for (let item of list) { map[item[id]] = item; } return map; } function timeout(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function tryCachedUserList(user, type) { let userlistWrapper = localStorage.getItem('MAL#' + type + 'list'); if (userlistWrapper) { userlistWrapper = JSON.parse(userlistWrapper); } if (!(userlistWrapper && userlistWrapper.fetchDate && ((new Date() - new Date(userlistWrapper.fetchDate)) / 3600000 < 1))) { let userlist = await fetchUserList(user, type); userlistWrapper = { "userlist": userlist, "fetchDate": new Date() }; localStorage.setItem('MAL#' + type + 'list', JSON.stringify(userlistWrapper)); } return userlistWrapper.userlist; } async function fetchUserList(user, type, userlist = [], page = 1) { await fetch('https://myanimelist.net/' + type + 'list/' + user + '/load.json?offset=' + ((page - 1) * 300)).then(function(response) { return response.json(); }).then(async function(json) { userlist = userlist.concat(json); if (json.length !== 0) { await timeout(1000); userlist = await fetchUserList(user, type, userlist, ++page); } }); return userlist; }