MAL Voice Actor Filter

This script filters voice actor: "Voice Acting Roles" and anime staff: "Anime Staff Positions" by your anime list entries

当前为 2014-10-16 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// MAL Voice Actor Filter!
// version 1.2
// 2010-06-14
// Copyright (c) 2009, Bastvera <[email protected]>
// 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=*
// @description    This script filters voice actor: "Voice Acting Roles" and anime staff: "Anime Staff Positions" by your anime list entries
// @author         Bastvera <[email protected]>
// @version        1.2.3
// ==/UserScript==
 
//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);
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){
	
    //Elements placing
    var checkboxAnchor = allEdits.snapshotItem(0);
    checkboxAnchor = checkboxAnchor.parentNode.parentNode.parentNode.parentNode.parentNode.previousSibling;
		
    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";
	
    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 {
        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 = GM_getValue('checkboxmem'); //Get chceckbox status
    if(checkboxmem==null){
        checkboxmem=false;
        GM_setValue('checkboxmem', checkboxmem);
        checkbox.checked=checkboxmem;
    }
    else{
        checkbox.checked=checkboxmem;
        if(checkbox.checked==true){
            HideDivs(editdivStaff);
        }
    }

    //Collect Plan to Watch divs
    var editPlan = [];
    //editPlan = CollectPlan();
    CollectPlan();

    //Listener
    checkbox.addEventListener('change',function () {
			
        if(checkbox.checked==true){
            HideDivs(editdivStaff);
        }

        if(checkbox.checked==false){
            RestoreDivsStaff();
        }
		
		GM_setValue('checkboxmem', 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 = GM_getValue('saveTime');
            modTime = "" + modTime;
            if(modTime!=saveTime){					//Cache time check
                GM_setValue('saveTime', modTime);
                checkboxText('Filter entries by your Anime List. (Downloading Plan to Watch entries...)');
    //newElement.appendChild(document.createTextNode('222'));
    //checkboxAnchor.appendChild(newElement);

            }
            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++;
                                }
							}   
						}							
                        GM_setValue('list', key); //Store Cache string
                        CollectDivs(ListLinks);
                        checkboxText('Filter entries by your Anime List.');
                    }
                });
            }
			
            else{
                var ListLinks = [];								//Anime Links Array
                var key = GM_getValue('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);
                checkboxText('Filter entries by your Anime List.');
            }
        }
    });

    function CollectDivs(ListLinks){

                /*
                var editParent = [];		//Main div
                var editSibling = [];		//Anime Link href for comparing
                //var editPlan = [];			//Plan to Watch div
            
                for (var i = 0; i < allEdits.snapshotLength; i++){
                    editParent[i] = editdiv[i].parentNode.parentNode;
                    editSibling[i] = editdiv[i].parentNode.firstChild;	//Anime Name;
            			
                    //Store "Plan to Watch" Divs
                    var convert = editSibling[i].href;
                    //for (var tcount in ListLinks){ <-------------------------------------------
                    //}
                }*/
    
        //var editParent = [];		//Main div
        var editSibling = [];		//Anime Link href for comparing
        //var editPlan = [];			//Plan to Watch div
    
        for (var i = 0; i < allEdits.snapshotLength; i++){
            //editParent[i] = editdiv[i].parentNode.parentNode;
            editSibling[i] = editdiv[i].parentNode.firstChild;	//Anime Name;

            StorePlan(i);
        }
    
        for (var i = 0; i < allEditsStaff.snapshotLength; i++){
            //editParent[i] = editdivStaff[i].parentNode.parentNode.parentNode;
            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;
                }
            }
        }
    }
    //return editPlan;
}

function checkboxText(text){
    newElement.style.display="none"; 				//Please wait off
    newElement = document.createElement('label');
    newElement.appendChild(document.createTextNode(text));
    checkboxAnchor.appendChild(newElement);
    newElement.style.fontWeight="normal";
    newElement.style.fontSize="10px";
}

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(/&nbsp;/,"");										//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
					
            for( curpos ; curpos < allEdits.snapshotLength; curpos++){
                if(moe[curpos].href==moe[current].href){ //Compare entries by moe name ^_^
		 
                    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(/&nbsp;/,"");
                    line = document.createTextNode('\n'+temp);
                    editdiv[current].parentNode.appendChild(line);
							
                    //Hide Similar Div
                    editdiv[curpos].parentNode.parentNode.style.display="none";
                }
            }

            for (var i in editPlan){        
                if(editPlan[i] == editdiv[current].parentNode.firstChild.href){
                    editdiv[current].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 ^_^
	
                    var br = document.createElement('br');
							
                    //Add Similar anime name
                    editdivStaff[current].parentNode.appendChild(br);
                    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 RestoreDivsStaff(){

    //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 Plan to Watch
    //for (var i in editPlan){
    //    editPlan[i].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[1]//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;
}