- // MAL Voice Actor Filter!
- // version 1.2
- // 2010-06-14
- // Copyright (c) 2009, Bastvera <bastvera@gmail.com>
- // Released under the GPL license
- // http://www.gnu.org/copyleft/gpl.html
- //
- // --------------------------------------------------------------------
- //
- // This is a Greasemonkey user script.
- //
- // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
- // Then restart Firefox and revisit this script.
- // Under Tools, there will be a new menu item to "Install User Script".
- // Accept the default configuration and install.
- //
- // To uninstall, go to Tools/Manage User Scripts,
- // select "MAL Voice Actor Filter", and click Uninstall.
- //
- // --------------------------------------------------------------------
- //
- // ==UserScript==
- // @name MAL Voice Actor Filter
- // @namespace http://thayanger.neostrada.pl
- // @include http://myanimelist.net/people/*
- // @include http://myanimelist.net/people.php?id=*
- // @include https://myanimelist.net/people/*
- // @include https://myanimelist.net/people.php?id=*
- // @description This script filters voice actor: "Voice Acting Roles" and anime staff: "Anime Staff Positions" by your anime list entries
- // @author Bastvera <bastvera@gmail.com>
- // @version 1.2.16
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
-
- setTimeout(function(){
- //All edit buttons in "Voice Acting Roles"
- var allEdits = document.evaluate(
- "//td[@style='padding-left: 5px;']//table[1]//a[@class='Lightbox_AddEdit button_edit']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
- //All edit buttons in "Anime Staff Positions"
- var allEditsStaff = document.evaluate(
- "//td[@style='padding-left: 5px;']//table[2]//a[@class='Lightbox_AddEdit button_edit']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
-
- //Correct Table check
- var antyStaff = allEdits.snapshotItem(0);
- if (antyStaff == null) {
- antyStaff = allEditsStaff.snapshotItem(0);
- var staffIndex = 2;
- } else {
- var staffIndex = 1;
- }
- antyStaff = antyStaff.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling;
- var convert=antyStaff.innerHTML;
- var finder = convert.search("Voice Acting Roles");
- var finderStaff = convert.search("Anime Staff Positions");
-
- if(finder!=-1 || finderStaff!=-1){
- var normalHeader = document.evaluate(
- "//div[@class='normal_header']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
- //Elements placing
- var checkboxAnchor = normalHeader.snapshotItem(0);
-
- var newElement = document.createElement('BR');
- checkboxAnchor.appendChild(newElement);
-
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.defaultChecked = false;
- checkboxAnchor.appendChild(checkbox);
-
- newElement = document.createElement('label');
- newElement.setAttribute('for','firstName');
- newElement.appendChild(document.createTextNode('Filter entries by your Anime List.'));
- checkboxAnchor.appendChild(newElement);
- newElement.style.fontWeight="normal";
- newElement.style.fontSize="10px";
-
- var newElement2 = document.createElement('label');
- newElement2.appendChild(document.createTextNode(' (Downloading Plan to Watch entries...)'));
- checkboxAnchor.appendChild(newElement2);
- newElement2.style.fontWeight="normal";
- newElement2.style.fontSize="10px";
-
- if (finder!=-1){
- //Arrays for storing elements
- var editdiv = []; //Edit button Div
- var moe = []; //Char Name
- var role = []; //Main/Support Div
-
- //Edit Entries Segments
- for (var i = 0; i < allEdits.snapshotLength; i++){
- var AnchorLink = allEdits.snapshotItem(i);
- editdiv[i] = AnchorLink.parentNode; //Edit button Div
- role[i] = editdiv[i].parentNode.nextSibling.nextSibling.lastChild; //Main/Support Div
- moe[i] = editdiv[i].parentNode.nextSibling.nextSibling.firstChild; //Char Name
- }
- } else {
- if (allEdits.snapshotItem(0) != null) {
- allEditsStaff = allEdits;
- }
- }
-
- //Arrays for storing elements
- var editdivStaff = []; //Edit button Div
- var moe2 = []; //Anime Name
-
- //Edit Entries Segments
- for (var i = 0; i < allEditsStaff.snapshotLength; i++){
- var AnchorLink = allEditsStaff.snapshotItem(i);
- editdivStaff[i] = AnchorLink; //Edit button Div
- moe2[i] = editdivStaff[i].parentNode.parentNode.firstChild; //Anime Name
- }
-
- //All add buttons in "Voice Acting Roles"
- var allElements = document.evaluate(
- "//td[@style='padding-left: 5px;']//a[@class='Lightbox_AddEdit button_add']", //"//td[@style='padding-left: 5px;']//table[1]//a[@class='Lightbox_AddEdit button_add']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
-
- //Array with add buttons div
- var addbutton = [];
- for (i = 0; i < allElements.snapshotLength; i++){
- AnchorLink = allElements.snapshotItem(i);
- addbutton[i] = AnchorLink.parentNode.parentNode.parentNode; //Main Div with Add button
- }
-
- //Div backup
- var backup = [];
- var orginal = [];
- var backpos = 0;
-
- //Get or Set status of checkbox
- var checkboxmem = (localStorage.getItem('checkboxmem_voice') === "true"); //Get chceckbox status
- if(checkboxmem==null){
- checkboxmem=false;
- localStorage.setItem('checkboxmem_voice', checkboxmem);
- checkbox.checked=checkboxmem;
- }
- else{
- checkbox.checked=checkboxmem;
- if(checkbox.checked==true){
- HideDivs();
- }
- }
-
- //Collect Plan to Watch divs
- var editPlan = [];
- CollectPlan();
-
- //Listener
- checkbox.addEventListener('change',function () {
-
- if(checkbox.checked==true){
- HideDivs();
- }
-
- if(checkbox.checked==false){
- RestoreDivs();
- }
-
- localStorage.setItem('checkboxmem_voice', checkbox.checked);
-
- },false)
- }
-
- function CollectPlan(){
- //Get username
- var allNavs = document.evaluate(
- "//div[@id='menu_left']//ul[@id='nav']//a",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
-
- var userName;
- for (var i = 0; i < allNavs.snapshotLength; i++){
- var linkNav = allNavs.snapshotItem(i);
- var userTest=/\/profile\/.*/;
- var getName = userTest.exec(linkNav);
- getName = "" + getName;
- getName = getName.replace(/\/profile\//,"");
- if(getName!='null')
- userName=getName;
- }
-
- var rssURL = "http://myanimelist.net/rss.php?type=rw&u=" + userName;
-
- //RSS change check
- GM_xmlhttpRequest({
- method: 'GET',
- url: rssURL,
- headers: {
- 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
- 'Accept': 'application/atom+xml,application/xml,text/xml',
- },
- onload: function(responseDetails){
-
- //Cache test
- var cacheCheck = 0;
-
- var lastTime = /<pubDate>.*<\/pubDate>/;
- var modTime = lastTime.exec(responseDetails.responseText);
- var saveTime = localStorage.getItem('saveTime');
- modTime = "" + modTime;
- if(modTime!=saveTime){ //Cache time check
- localStorage.setItem('saveTime', modTime);
- }
- else
- cacheCheck++;
-
- if(cacheCheck==0){
- //User list
- var animeURL = "http://myanimelist.net/malappinfo.php?u=" + userName + "&status=all";
- GM_xmlhttpRequest({
- method: 'GET',
- url: animeURL,
- headers: {
- 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
- 'Accept': 'application/atom+xml,application/xml,text/xml',
- },
- onload: function(responseDetails){
- var text = responseDetails.responseText;
-
- var key = ";"; //Chaching string
-
- //Edit Anime links formating
- var tagcount = 5000; //Max number of anime entries
- var plancount = 0; //Counter "Plan to Watch" entries
- var ListLinks = []; //Array for anime entries storing
- var anireg=/<series_animedb_id>\d{1,}<\/series_animedb_id>/g; //Anime entries links
- var anistatus=/<my_status>\d{1}<\/my_status>/g; //Anime entries status
- var exactlink=/\d{1,}/; //Anime exact link
-
- for (var i = 0; i < tagcount; i++){
- var linkGet = anireg.exec(text);
- if(linkGet==null){
- tagcount=i;
- break;
- }
- else {
- var planDetect = anistatus.exec(text);
- if(planDetect=="<my_status>6</my_status>"){
- ListLinks[plancount] = linkGet;
- ListLinks[plancount] = exactlink.exec(ListLinks[plancount]);
- key = key + ListLinks[plancount] + ";";
- ListLinks[plancount] = "http://myanimelist.net/anime/" + ListLinks[plancount] + "/";
- plancount++;
- }
- }
- }
- localStorage.setItem('list', key); //Store Cache string
- CollectDivs(ListLinks);
- if(checkbox.checked==true){
- RestoreDivs();
- HideDivs();
- }
- newElement2.style.display="none";
- }
- });
- }
-
- else{
- var ListLinks = []; //Anime Links Array
- var key = localStorage.getItem('list'); //Fetch link from Cache
- var exactlink=/\d{1,}/g;
- var tagcount = 5000;
- for (var i = 0; i < tagcount; i++){
- var linkGet = exactlink.exec(key);
- if(linkGet==null){
- tagcount=i;
- break;
- }
- else{
- ListLinks[i]=linkGet;
- ListLinks[i] = "http://myanimelist.net/anime/" + ListLinks[i] + "/";
- }
- }
- CollectDivs(ListLinks);
- if(checkbox.checked==true){
- RestoreDivs();
- HideDivs();
- }
- newElement2.style.display="none";
- }
- }
- });
-
- function CollectDivs(ListLinks){
- var editSibling = []; //Anime Link href for comparing
-
- if(finder!=-1){
- for (var i = 0; i < allEdits.snapshotLength; i++){
- editSibling[i] = editdiv[i].parentNode.firstChild; //Anime Name;
-
- StorePlan(i);
- }
- }
-
- for (var i = 0; i < allEditsStaff.snapshotLength; i++){
- editSibling[i] = moe2[i]; //Anime Name;
-
- StorePlan(i);
- }
-
- function StorePlan(i){
- //Store "Plan to Watch" Divs
- var convert = editSibling[i].href;
- var exactlink=/\d{1,}/;
- convert = "http://myanimelist.net/anime/" + exactlink.exec(convert) + "/"; //Anime Link;
-
-
- for (var tcount in ListLinks){
- var finderPlan = convert.search(ListLinks[tcount]);
- if(finderPlan!=-1){
- editPlan.push(editSibling[i]);
- break;
- }
- }
- }
- }
- }
-
- function HideDivs(){
- //Hide all div with add
- for (var current in addbutton){
- addbutton[current].style.display="none";
- }
-
- //Hide edit Div
- var current;
- for (current in editdivStaff){
- editdivStaff[current].style.display="none";
- }
-
- for(current in moe){
-
- var curpos = current;
- curpos++;
-
- if(editdiv[current].parentNode.parentNode.getAttribute('style')!="display: none;"){ //Modify root entries only
-
- //Div backup storage
- backup[backpos] = editdiv[current].parentNode.parentNode.cloneNode(true);
- orginal[backpos] = editdiv[current].parentNode.parentNode;
- backpos++;
-
- //Root /Main/Support text add
- var temp = role[current].innerHTML; //Main/Support text
- temp = temp.replace(/ /,""); //Main/Support clear
- var line = document.createTextNode('\n'+ temp);
- editdiv[current].parentNode.appendChild(line);
-
- //Root hide elements
- role[current].style.display="none"; //Hide Main/Support Div
- editdiv[current].style.display="none"; //Hide edit and airing Div
-
- var currentPlanned = false;
- for (var i in editPlan){
- if(editPlan[i] == editdiv[current].parentNode.firstChild.href){
- currentPlanned = true;
- editdiv[current].parentNode.parentNode.style.display="none";
- }
- }
-
- if (!currentPlanned) {
- for( curpos ; curpos < allEdits.snapshotLength; curpos++){
- if(moe[curpos].href==moe[current].href){ //Compare entries by moe name ^_^
- var planned = false;
- for (var i in editPlan) {
- if(editPlan[i] == editdiv[curpos].parentNode.firstChild.href) {
- planned = true;
- }
- }
- if (!planned) {
- var br = document.createElement('br');
-
- //Add Similar anime name
- editdiv[current].parentNode.appendChild(br);
- var newNode=editdiv[curpos].parentNode.firstChild.cloneNode(true);
- editdiv[current].parentNode.appendChild(newNode);
-
- //Similar /Main/Support text add
- temp = role[curpos].innerHTML;
- temp = temp.replace(/ /,"");
- line = document.createTextNode('\n'+temp);
- editdiv[current].parentNode.appendChild(line);
-
- //Hide Similar Div
- editdiv[curpos].parentNode.parentNode.style.display="none";
- }
- }
- }
- }
- }
- }
-
- for(current in moe2){
-
- var curpos = current;
- curpos++;
-
- if(editdivStaff[current].parentNode.parentNode.parentNode.getAttribute('style')!="display: none;"){ //Modify root entries only
-
- //Div backup storage
- backup[backpos] = editdivStaff[current].parentNode.parentNode.parentNode.cloneNode(true);
- orginal[backpos] = editdivStaff[current].parentNode.parentNode.parentNode;
- backpos++;
-
- for( curpos ; curpos < allEditsStaff.snapshotLength; curpos++){
- if(moe2[curpos].href==moe2[current].href){ //Compare entries by anime name ^_^
-
- //Add Similar anime name
- var newNode=editdivStaff[curpos].parentNode.cloneNode(true);
- editdivStaff[current].parentNode.parentNode.appendChild(newNode);
-
- //Hide Similar Div
- editdivStaff[curpos].parentNode.parentNode.parentNode.style.display="none";
- }
- }
-
- for (var i in editPlan){
- if(editPlan[i] == moe2[current].href){
- editdivStaff[current].parentNode.parentNode.parentNode.style.display="none";
- }
- }
- }
- }
- }
-
- function RestoreDivs(){
-
- //Restore Modified Divs
- for(var current in backup){
- orginal[current].parentNode.replaceChild(backup[current],orginal[current]);
- }
-
- //Unhide Similar Voice Actor
- for(current in editdiv){
- editdiv[current].parentNode.parentNode.removeAttribute('style');
- }
-
- //Unhide Similar Staff
- for(current in editdivStaff){
- editdivStaff[current].parentNode.parentNode.parentNode.removeAttribute('style');
- }
-
- //Unhide add entries
- for(current in addbutton){
- addbutton[current].removeAttribute('style');
- }
-
- if (finder!=-1){
- //Rescan all edit entries
- allEdits = document.evaluate(
- "//td[@style='padding-left: 5px;']//table[1]//a[@class='Lightbox_AddEdit button_edit']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
-
- for (var i = 0; i < allEdits.snapshotLength; i++){
- AnchorLink = allEdits.snapshotItem(i);
- editdiv[i] = AnchorLink.parentNode; //Edit button Div
- role[i] = editdiv[i].parentNode.nextSibling.nextSibling.lastChild; //Main/Support Div
- moe[i] = editdiv[i].parentNode.nextSibling.nextSibling.firstChild; //Char Name
- }
-
- //Rescan all edit entries
- allEditsStaff = document.evaluate(
- "//td[@style='padding-left: 5px;']//table[2]//a[@class='Lightbox_AddEdit button_edit']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
- }
-
- if (finderStaff!=-1) {
- //Rescan all edit entries
- allEditsStaff = document.evaluate(
- "//td[@style='padding-left: 5px;']//table["+staffIndex+"]//a[@class='Lightbox_AddEdit button_edit']",
- document,
- null,
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
- null);
- }
-
- for (var i = 0; i < allEditsStaff.snapshotLength; i++){
- AnchorLink = allEditsStaff.snapshotItem(i);
- editdivStaff[i] = AnchorLink; //Edit button Div
- }
-
- //Unhide edit entries
- for(current in editdivStaff){
- editdivStaff[current].removeAttribute('style');
- }
-
- //Reset backups
- backup = [];
- orginal = [];
- backpos = 0;
- }
- }, 100);