Show anime info inside your animelist
目前為
// ==UserScript==
// @name MyAnimeList(MAL) - Extra
// @version 3.0.1
// @description Show anime info inside your animelist
// @author Cpt_mathix
// @match *://myanimelist.net/animelist/*
// @match *://myanimelist.net/mangalist/*
// @license GPL version 2 or any later version; http://www.gnu.org/licenses/gpl-2.0.txt
// @grant GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/16080
// ==/UserScript==
// -----------------------------------------SETTINGS----------------------------------------- //
var transparentNotYetAired = true; // set to false if you don't want "Not Yet Aired" transparent
// ------------------------------------------------------------------------------------------ //
var dataMap = [];
var dataArray = [];
var href = document.location.href;
var user = href.substr(href.lastIndexOf('/') + 1);
var type = [];
if(window.location.href.indexOf("mangalist") > -1) {
type = ["manga",65];
} else {
type = ["anime",64];
}
var xmlDoc;
initList();
function initList() {
var table = document.getElementById("list_surround").children;
for (var i = 0; i < table.length; i++) {
var cell = table[i].getElementsByTagName('td');
for (var j = 0; j < cell.length; j++) {
var hasMore = cell[j].innerHTML.search('More');
if (hasMore != -1) {
// get anime title
var animeTitle = cell[j].getElementsByClassName('animetitle')[0].innerText.replace(/ /g,"-");
// get titleid
var a = cell[j].getElementsByTagName("a");
var titleid = a[1].getAttribute('onclick').match(/\d.*,/g).join("").replace(',',"");
// get table color type
var tdtype = cell[j].className.match(/\d/g).join("");
// replace onclick function with my own
a[1].removeAttribute('onclick');
a[1].addEventListener('click', displayTable(animeTitle, titleid, tdtype) , true);
}
// Not Yet Aired transparant
var found = cell[j].innerHTML.search('Not Yet Aired');
if (found != -1 && transparentNotYetAired) {
cell[j].setAttribute('style', 'opacity:0.50 !important');
// table[i].setAttribute('style', 'display:none !important');
}
}
}
}
//--------------------------------//
// Get Data Functions //
//--------------------------------//
/*
function getAnimeInfoExternal(animeid, table) {
$.get('http://myanimelist.net/includes/ajax.inc.php?t=' + type[1] + '&id=' + animeid, function(data) {
$(data).filter('.dark_text').each(function() {
dataArray.push(this.nextSibling.textContent);
});
});
}
*/
function getAnimeInfo(animeid, table) {
if (xmlDoc === undefined) {
xmlDoc = getUserListInfo();
}
$.get('http://myanimelist.net/' + type[0] + '/' + animeid, function(data) {
$(data).find('#content > table > tbody > tr > td.borderClass > div:nth-child(n) > span').each(function() {
var item = this.textContent.replace(/:/g,"");
if (isNaN(item) && (this.nextElementSibling === null || item == "Ranked")) {
dataMap.push(item);
dataArray.push(this.nextSibling.textContent);
} else if (isNaN(item) && item.indexOf(',') == -1) {
dataMap.push(item);
var information = this.parentNode.children[1].outerHTML;
for(var i = 2; i < this.parentNode.children.length && item != "Score"; i++) {
information += ", " + this.parentNode.children[i].outerHTML;
}
dataArray.push(information);
}
});
$(data).find('#content > table > tbody > tr > td:nth-child(2) > table > tbody > tr:nth-child(1) > td > span').each(function() {
dataMap.push('Synopsis');
dataArray.push(this.innerHTML);
});
$(data).find('#content > table > tbody > tr > td:nth-child(2) > table > tbody > tr:nth-child(2) > td > table.anime_detail_related_anime > tbody > tr:nth-child(n) > td.ar.fw-n.borderClass').each(function() {
var related = this.textContent.replace(/:/g,"");
if (related == "Parent story") {
dataMap.push('Parent');
dataArray.push(this.nextElementSibling.innerHTML);
} else if (related == "Side story" && this.nextElementSibling.children.length <= 3) {
dataMap.push('Side');
dataArray.push(this.nextElementSibling.innerHTML);
} else if (related == "Prequel") {
dataMap.push('Prequel');
dataArray.push(this.nextElementSibling.innerHTML);
} else if (related == "Sequel") {
dataMap.push('Sequel');
dataArray.push(this.nextElementSibling.innerHTML);
} else if (related == "Alternative version") {
dataMap.push('Alternative');
dataArray.push(this.nextElementSibling.innerHTML);
}
});
table.innerHTML = displayAnimeInfo(animeid);
});
}
function getUserListInfo() {
var xhr = new XMLHttpRequest();
var url = 'http://myanimelist.net/malappinfo.php?u=' + user + '&status=all&type=' + type[0] + '';
xhr.open("GET", url, false);
xhr.setRequestHeader('Content-Type', 'text/xml');
xhr.send();
var xmlDocument = xhr.responseXML;
return xmlDocument;
}
function getDataFromOriginalMore(preData) {
var start = preData.indexOf('Time Spent Watching');
var end = preData.indexOf('<small>(');
dataMap.push('TimeSpentWatching');
dataArray.push(preData.substring(start + 21, end));
start = end;
end = preData.indexOf('per episode');
var episodeTime = preData.substring(start + 8, end);
dataMap.push('EpisodeTime');
dataArray.push(episodeTime);
}
//--------------------------------//
// Display Data Functions //
//--------------------------------//
// if this fails to function, look at getExpand(arg1, arg2) function on the myanimelist page
function displayTable(animetitle, animeid, tdtype) {
return function () {
var moreObject = $('#more'+animeid);
var memberId = $('#listUserId').val();
if (moreObject.css('display') == 'block') { // Hide if loaded
moreObject.hide();
return false;
}
if (moreObject.children().length != 0 && xmlDoc !== undefined && moreObject[0].className == "Hide extraLoaded") { // Show if data is already loaded
moreObject.show();
return false;
}
$.post("/includes/ajax-no-auth.inc.php?t=6", {color:tdtype,id:animeid,memId:memberId,type:$('#listType').val()}, function(data) {
moreObject.html(data.html).show();
// change info with info from API request
var hiddendiv = "more" + animeid;
var table = document.getElementById(hiddendiv).getElementsByClassName('td' + tdtype + ' borderRBL')[0];
dataMap.length = 0;
dataArray.length = 0;
if (table !== null && type[0] != "manga") {
getDataFromOriginalMore(table.innerHTML);
table.innerHTML = "Fetching data";
getAnimeInfo(animeid, table);
} else if (table !== null) {
table.innerHTML = "Fetching data";
getAnimeInfo(animeid, table);
}
moreObject[0].className = moreObject[0].className + " extraLoaded";
}, "json");
};
}
function getDataValue(string) {
var elementPos = dataMap.map(function(x) {return x; }).indexOf(string);
if (dataArray[elementPos] === undefined)
return "Unavailable";
return dataArray[elementPos];
}
function getXmlEntry(animeid, string) {
var entry = xmlDoc.getElementsByTagName(type[0]);
var entryid = xmlDoc.getElementsByTagName('series_' + type[0] + 'db_id');
for(var k = 0; k < entryid.length; k++) {
if (entryid[k].textContent == animeid) {
return entry[k].getElementsByTagName('series_' + string)[0].textContent;
}
}
}
function calcTimeNeeded(episodeTime, totalEpisodes) {
if (totalEpisodes.trim() == "0" || totalEpisodes == "Unknown") {
return 'Unknown';
} else if (episodeTime.indexOf("0 hours, 0 minutes, and 0 seconds") > -1) {
return 'Unknown';
} else if (totalEpisodes.trim() == "1") {
return episodeTime;
} else {
var str = episodeTime.split(' ');
var totalSeconds = parseInt(str[5]) * totalEpisodes + (parseInt(str[2]) * totalEpisodes * 60) + (parseInt(str[0]) * totalEpisodes * 60 * 60);
var seconds = totalSeconds % 60;
var totalMinutes = Math.floor(totalSeconds/60);
var minutes = totalMinutes % 60;
var hours = Math.floor(totalMinutes/60);
return hours + " hours, " + minutes + " minutes and " + seconds + " seconds";
}
}
function displayAnimeInfo(animeid) {
var episodes = getDataValue('Episodes');
var image = getXmlEntry(animeid, "image");
var genres = getDataValue('Genres');
var status = getDataValue('Status');
var broadcast = getDataValue('Broadcast');
var score = getDataValue('Score');
var rank = getDataValue('Ranked').replace("#","");
var popularity = getDataValue('Popularity').replace("#","");
var studio = getDataValue('Studios');
var parent = getDataValue('Parent');
var side = getDataValue('Side');
var prequel = getDataValue('Prequel');
var sequel = getDataValue('Sequel');
var alternative = getDataValue('Alternative');
var synopsis = getDataValue('Synopsis').replace(/\(Source.*[\s\S]*/g,"").replace(/\[.*\]/g,"");
var timeSpentWatching = getDataValue('TimeSpentWatching').replace("tes,","tes");
var timeNeeded = 0;
if (timeSpentWatching.indexOf("0 hours, 0 minutes and 0 seconds") > -1) {
timeNeeded = calcTimeNeeded(getDataValue('EpisodeTime'), episodes);
}
var startDate = getXmlEntry(animeid, 'start').replace(/\d\d\d\d-\d\d-\d\d/g, function(s) {
var dmy = s.split('-');
return dmy[2] + '/' + dmy[1] + '/' + dmy[0];
});
var endDate = "";
if (startDate == "00/00/0000") {
startDate = "N/A";
} else {
endDate = getXmlEntry(animeid, 'end').replace(/\d\d\d\d-\d\d-\d\d/g, function(s) {
var dmy = s.split('-');
return dmy[2] + '/' + dmy[1] + '/' + dmy[0];
});
if (episodes.trim() == "1") {
endDate = "";
} else if (endDate == "00/00/0000") {
endDate = " " + "to N/A";
} else {
endDate = " to " + endDate;
}
}
// console.log(dataMap);
// console.log(dataArray);
var strVar="";
strVar += "<body>";
strVar += "<table>";
strVar += " <tr>";
strVar += " <td valign=\"top\" rowspan=\"4\">" + "<img src=" + image + ">" + "<\/td>";
strVar += " <td valign=\"top\" width=\"35%\">";
if (status.indexOf("Currently Airing") > -1)
strVar += "<b>" + "Broadcast: " + "<\/b>" + broadcast + "<br>";
strVar += " <b>" + "Episodes: " + "<\/b>" + episodes + "<br>";
strVar += " <b>" + "Score: " + "<\/b>" + score + "<br>";
strVar += " <b>" + "Rank: " + "<\/b>" + rank + "<br>";
strVar += " <b>" + "Popularity: " + "<\/b>" + popularity + "<br>";
if (studio.indexOf("add some") == -1)
studio.indexOf(",") > -1 ? (strVar += "<b>" + "Studios: " + "<\/b>" + studio + "<br>") : (strVar += "<b>" + "Studio: " + "<\/b>" + studio + "<br>");
strVar += " <b>" + "Aired: " + "<\/b>" + startDate + endDate + "<br>";
strVar += " <\/td>";
strVar += " <td valign=\"top\" align=\"right\" width=\"65%\">" + genres + "<\/td>";
strVar += " <\/tr>";
strVar += " <tr>";
strVar += " <td valign=\"top\" colspan=\"2\" width=\"100%\" height=\"100%\">" + "<br>" + synopsis + "<\/td>";
strVar += " <\/tr>";
strVar += " <tr>";
strVar += " <td valign=\"bottom\" align=\"left\" height=\"5px\" width=\"50%\">";
if (parent != "Unavailable")
strVar += "<small>" + "<b>" + "Parent story: " + "<\/b>" + parent + "<\/small>";
if (side != "Unavailable")
strVar += "<br>" + "<small>" + "<b>" + "Side story: " + "<\/b>" + side + "<\/small>";
if (prequel != "Unavailable")
strVar += "<br>" + "<small>" + "<b>" + "Prequel: " + "<\/b>" + prequel + "<\/small>";
if (sequel != "Unavailable")
strVar += "<br>" + "<small>" + "<b>" + "Sequel: " + "<\/b>" + sequel + "<\/small>";
if (alternative != "Unavailable")
strVar += "<br>" + "<small>" + "<b>" + "Alternative version: " + "<\/b>" + alternative + "<\/small>";
strVar += " <\/td>";
strVar += " <td valign=\"bottom\" align=\"right\" colspan=\"2\">" + "<br>" + "<small>" + (timeNeeded == 0 ? ("<b>" + "Time Spent Watching: " + "<\/b>" + timeSpentWatching) : ("<b>" + "Time To Complete: " + "<\/b>" + timeNeeded)) + "<\/small>" + "<\/td>";
strVar += " <\/tr>";
strVar += "<\/table>";
strVar += "<\/body>";
return strVar;
}