Last active
April 1, 2026 18:29
-
-
Save virtalas/9abaf0d13dc9a6678d11 to your computer and use it in GitHub Desktop.
Find out easily what anime you have rewatched by executing this script on your myanimelist.net 'Completed' list page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * MyAnimeList Rewatch Counter | |
| * (+ reread manga) | |
| * | |
| * This is a tool to easily and quickly make a list of what anime you have rewatched and how many times. | |
| * Also works for reread manga. | |
| * | |
| * HOW TO USE: | |
| * Go to a myanimelist.net anime/manga list, and choose the 'Completed' view. | |
| * Open a JavaScript console on your browser and paste this code into it and press enter. | |
| * The script will read all 'More' views on the list, and after a few seconds generate the rewatch/reread list. | |
| * | |
| * NOTE on the new default list style: | |
| * The script will work, but you will have to manually scroll the list to load all titles onto the page before executing. | |
| */ | |
| var url = window.location.href.split('?')[0]; | |
| var type = ""; | |
| if (url.indexOf("myanimelist.net/animelist") > -1) { | |
| type = "anime"; | |
| } else if (url.indexOf("myanimelist.net/mangalist") > -1) { | |
| type = "manga"; | |
| } else { | |
| alert("Execute this on a MyAnimeList.net anime/manga list page!"); | |
| throw new Error("Execute this on a MyAnimeList.net anime/manga list page!"); | |
| } | |
| // Works only on the 'Completed' page | |
| if (getParameterByName('status') != 2) { | |
| alert("Execute this on the 'Completed' page! \nRedirecting. \nTry again after the page loads."); | |
| window.location.replace(url + "?status=2"); | |
| throw new Error("Redirecting"); | |
| } | |
| var username = url.split('/').pop(); | |
| var titles_old = document.querySelectorAll('div table tbody tr a.animetitle span'); | |
| var titles_new = document.querySelectorAll('tbody.list-item tr.list-table-data td.data.title a.link.sort'); | |
| var titles = []; | |
| var old_list = false; | |
| if (titles_old.length > titles_new.length) { | |
| titles = titles_old; | |
| old_list = true; | |
| } else { | |
| for (var i = 0; i < titles_new.length; i++) { | |
| titles[i] = titles_new[i].innerHTML; | |
| } | |
| } | |
| var rewatches = []; | |
| var moreLinks = document.querySelectorAll('a'); | |
| var resultArray = []; | |
| var result = 'data:text/html;charset=utf-8,<style>html,body{margin: 0;padding: 0;}</style><div style="white-space: pre;width: 100%;max-width:650px;font-size: 18px;color:#444;height: 100%;border: none;outline: none;margin:40px auto;padding: 30px;">'; | |
| if (type == "anime") result += "<h1>Rewatched anime</h1>"; | |
| if (type == "manga") result += "<h1>Reread manga</h1>"; | |
| if (type == "anime") result += "<h3><em>How many times " + username + " has seen it</em></h3><br>"; | |
| if (type == "manga") result += "<h3><em>How many times " + username + " has read it</em></h3><br>"; | |
| if (old_list) { | |
| // Fetch rewatch count information bypassing the 'More' link | |
| $("div.hide").each(function(index,value){ | |
| var series_id = $(value).attr('id').split('more')[1]; | |
| $.post("/includes/ajax-no-auth.inc.php?t=6", {color:1,id:series_id,memId:$('#listUserId').val(),type:$('#listType').val()}, function(data) { | |
| if (type == "anime") rewatches[index] = $(data.html).find('strong')[0].innerHTML; | |
| if (type == "manga") { | |
| var moreSection = $(data.html).find('td').html(); | |
| var timesReadIndex = moreSection.indexOf("Times Read"); | |
| rewatches[index] = moreSection.charAt(timesReadIndex + 12); | |
| } | |
| }, "json"); | |
| }); | |
| } else { | |
| // Click all links labeled 'More' to get the rewatch counts on page | |
| for( var i=moreLinks.length; i--; ) { | |
| if (moreLinks[i].innerHTML == 'More') { | |
| moreLinks[i].click(); | |
| } | |
| } | |
| } | |
| // Progress bar | |
| $('body').append('<div id="progress" style="width: 600px;height: 20px;position: fixed;top:30%;left:50%;margin-left:-300px;border: 5px solid #ccc;"></div>') | |
| .append($('<div id="bar" style="text-align: left;width: 0px;height: 20px;position: fixed;top:30%;left:50%;margin-left:-295px;margin-top:5px;background-color: #479af9;white-space:pre;color:white;font-weight:bold;font-size:16px"></div>')); | |
| // Repeat every 1 second until all More-sections are processed | |
| wait(); | |
| function wait() { | |
| setTimeout(function () { | |
| if (!old_list) rewatches = document.querySelectorAll('tbody.list-item tr.more-info strong'); | |
| // Log progress | |
| console.log(rewatches.length + "/" + titles.length + " opened"); | |
| $('#bar').text(" " + rewatches.length + "/" + titles.length); | |
| $('#bar').css('width', rewatches.length / titles.length * 600 + 'px'); | |
| if (rewatches.length != titles.length) { | |
| // All sections aren't open yet, check again after 1 second | |
| wait(); | |
| } else { | |
| if (old_list) { | |
| // OLD list: | |
| for (var i = 0; i < titles.length; i++) { | |
| // Parse rewatched shows into an array of arrays with rewatch count as index | |
| if (rewatches[i] > 0) { | |
| if (resultArray[rewatches[i]]) { | |
| resultArray[rewatches[i]] = resultArray[rewatches[i]].concat("<li>" + titles[i].innerHTML + "</li>"); | |
| } else { | |
| resultArray[rewatches[i]] = "<b>" + (parseInt(rewatches[i]) + 1) + " times:</b>"; // +1 to change from rewatch count to watch count | |
| resultArray[rewatches[i]] = resultArray[rewatches[i]].concat("<ul>"); | |
| resultArray[rewatches[i]] = resultArray[rewatches[i]].concat("<li>" + titles[i].innerHTML + "</li>"); | |
| } | |
| } | |
| } | |
| } else { | |
| // NEW list: | |
| for (var i = 0; i < titles.length; i++) { | |
| // Parse rewatched shows into an array of arrays with rewatch count as index | |
| if (rewatches[i].innerHTML > 0) { | |
| if (resultArray[rewatches[i].innerHTML]) { | |
| resultArray[rewatches[i].innerHTML] = resultArray[rewatches[i].innerHTML].concat("<li>" + titles[i].trim() + "</li>"); | |
| } else { | |
| resultArray[rewatches[i].innerHTML] = "<b>" + (parseInt(rewatches[i].innerHTML) + 1) + " times:</b>"; // +1 to change from rewatch count to watch count | |
| resultArray[rewatches[i].innerHTML] = resultArray[rewatches[i].innerHTML].concat("<ul>"); | |
| resultArray[rewatches[i].innerHTML] = resultArray[rewatches[i].innerHTML].concat("<li>" + titles[i].trim() + "</li>"); | |
| } | |
| } | |
| } | |
| } | |
| resultArray.reverse(); | |
| resultArray.forEach(function (value, index, array) { | |
| result += value.concat("</ul>"); | |
| }); | |
| result += "<br><br><br><br></div>"; | |
| window.location = result; | |
| } | |
| }, 1000); | |
| } | |
| function getParameterByName(name) { | |
| name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); | |
| var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), | |
| results = regex.exec(location.search); | |
| return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-- Here is an updated version thar worked for me
var url = window.location.href.split('?')[0];
var type = "";
if (url.indexOf("myanimelist.net/animelist") > -1) {
type = "anime";
} else if (url.indexOf("myanimelist.net/mangalist") > -1) {
type = "manga";
} else {
alert("Execute this on a MyAnimeList.net anime/manga list page!");
throw new Error("Execute this on a MyAnimeList.net anime/manga list page!");
}
// Works only on the 'Completed' page
if (getParameterByName('status') != 2) {
alert("Execute this on the 'Completed' page! \nRedirecting. \nTry again after the page loads.");
window.location.replace(url + "?status=2");
throw new Error("Redirecting");
}
var username = url.split('/').pop();
var titles_old = document.querySelectorAll('div table tbody tr a.animetitle span');
var titles_new = document.querySelectorAll('tbody.list-item tr.list-table-data td.data.title a.link.sort');
var titles = [];
var old_list = false;
if (titles_old.length > titles_new.length) {
titles = titles_old;
old_list = true;
} else {
for (var i = 0; i < titles_new.length; i++) {
titles[i] = titles_new[i].innerHTML;
}
}
var rewatches = [];
var moreLinks = document.querySelectorAll('a');
var resultArray = [];
var result = '';
if (type == "anime") result += "Rewatched anime\n";
if (type == "manga") result += "Reread manga\n";
if (type == "anime") result += "How many times " + username + " has seen it:\n\n";
if (type == "manga") result += "How many times " + username + " has read it:\n\n";
if (old_list) {
$.post("/includes/ajax-no-auth.inc.php?t=6", {color:1,id:series_id,memId:$ ('#listUserId').val(),type:$('#listType').val()}, function(data) {
$("div.hide").each(function(index,value){
var series_id = $(value).attr('id').split('more')[1];
if (type == "anime") rewatches[index] = $(data.html).find('strong')[0].innerHTML;
if (type == "manga") {
var moreSection = $(data.html).find('td').html();
var timesReadIndex = moreSection.indexOf("Times Read");
rewatches[index] = moreSection.charAt(timesReadIndex + 12);
}
}, "json");
});
} else {
for( var i=moreLinks.length; i--; ) {
if (moreLinks[i].innerHTML == 'More') {
moreLinks[i].click();
}
}
}
$('body').append('
').append($(''));
wait();
function wait() {
setTimeout(function () {
if (!old_list) rewatches = document.querySelectorAll('tbody.list-item tr.more-info strong');
}, 1000);
}
function getParameterByName(name) {
name = name.replace(/[[]/, "\[").replace(/[]]/, "\]");
var regex = new RegExp("[\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/+/g, " "));
}