Yahoo Fantasy Football Rank

Very simple script to conveniently see how many points a team gives up

Version vom 07.09.2015. Aktuellste Version

// ==UserScript==
// @name             Yahoo Fantasy Football Rank
// @author           Bijan
// @version          2.9
// @description      Very simple script to conveniently see how many points a team gives up
// @namespace        http://albuyeh.com
// @match            *://football.fantasysports.yahoo.com/*
// @require          http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require          https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=19641
// @grant            GM_xmlhttpRequest
// @grant            GM_getValue
// @grant            GM_setValue
// @icon             http://albuyeh.com/FF/Icon.png
// ==/UserScript==


/* CHANGELOG
v2.4: Accidentaly had St Louis listed as 'Stl' and not 'StL'. This caused the script to break as soon as it saw a player/opposing team on St Louis :P
v2.5: I fixed something but forgot what it was
v2.6: Made script more versatille. Watched Mad Max. Fixed a lot of issues of script not showing player stats. Had some chicken nuggets too.
v2.7: Oops. Fixed for realsies.
v2.8: Update waitForKeyElements require to be GreasyFork compliant. Added IDP. Forced redownload
v2.9: Made script work on 'Opponents' page
*/

//Map Team Name to abbreviation
var teamNameList = {
    "Arizona Cardinals": "Ari",
    "Atlanta Falcons": "Atl",
    "Baltimore Ravens": "Bal",
    "Buffalo Bills": "Buf",
    "Carolina Panthers": "Car",
    "Chicago Bears": "Chi",
    "Cincinnati Bengals": "Cin",
    "Cleveland Browns": "Cle",
    "Dallas Cowboys": "Dal",
    "Denver Broncos": "Den",
    "Detroit Lions": "Det",
    "Green Bay Packers": "GB",
    "Houston Texans": "Hou",
    "Indianapolis Colts": "Ind",
    "Jacksonville Jaguars": "Jax",
    "Kansas City Chiefs": "KC",
    "Miami Dolphins": "Mia",
    "Minnesota Vikings": "Min",
    "New England Patriots": "NE",
    "New Orleans Saints": "NO",
    "New York Giants": "NYG",
    "New York Jets": "NYJ",
    "Oakland Raiders": "Oak",
    "Philadelphia Eagles": "Phi",
    "Pittsburgh Steelers": "Pit",
    "San Diego Chargers": "SD",
    "San Francisco 49ers": "SF",
    "Seattle Seahawks": "Sea",
    "St. Louis Rams": "StL",
    "Tampa Bay Buccaneers": "TB",
    "Tennessee Titans": "Ten",
    "Washington Redskins": "Was",
}

const playerPositions   = ["QB", "WR", "RB", "TE", "K", "DEF", "DB", "DL", "LB", "DT", "DE", "CB", "S"]; //Positions to fetch data for
const numPositions      = playerPositions.length;
const baseURL           = "http://football.fantasysports.yahoo.com/f1/326198/pointsagainst?pos="; //Page to create fetch request to
var rankingsTable       = {}; //This will be filled by the AJAX parser.
var final               = {}; //Final table that holds all of the team/position info
var result              = {};
var numPagesFetched     = 0;
var tableName           = "FF_Array3";

//Display notification of Update
var ver = GM_info.script.version; 
if (GM_getValue("version", "") < ver) {
    GM_setValue("version", ver);
    alert("Updated Yahoo Fantasy Football Rank by Bijan to version v" + ver);
}


//Fetch results once per day. 
var now = new Date();
var currdate = Math.floor(now/8.64e7);
if (GM_getValue("date2", "") < currdate || GM_getValue (tableName,  "").length == 0) {
    GM_setValue("date2", currdate);
    console.log("Fetched results @ :" + currdate);
    main(); //Go to main() to fetch data
}
else {
    console.log("Already fetched data. Continuing to display results");
    displayResults(); 
}

function main () {
    for (var J in playerPositions) {
        GM_xmlhttpRequest ( {
            method:     "GET",
            url:        baseURL + playerPositions[J],
            context:    playerPositions[J],
            onload:     parseResponse,
            onerror:    function (e) { console.error ('**** error ', e); },
            onabort:    function (e) { console.error ('**** abort ', e); },
            ontimeout:  function (e) { console.error ('**** timeout ', e); }
        } );
    }
}

function parseResponse (response) {
    var playerPosition  = response.context;
    var parser          = new DOMParser ();
    var ajaxDoc         = parser.parseFromString (response.responseText, "text/html");
    var statRows        = ajaxDoc.querySelectorAll ("#statTable0 > tbody > tr");
    var newStatTable    = $(statRows).map ( function () {
        var tblRow          = $(this);
        var teamRank        = parseInt (tblRow.find (".rank-indicator").text().trim(), 10);
        var teamName        = teamNameList[tblRow.find ("td:eq(1)").text().trim().split(" vs")[0]];

        return [ [teamName, teamRank] ];
    } ).get ();

    numPagesFetched++;
    console.log ('Fetched page ' + numPagesFetched + ' of ' + numPositions + '.');

    /*--- Now loop over the fetched rows and collate them into the master table, depending
          on playerPosition.
    */
    var columnIdx       = playerPositions.indexOf (playerPosition);

    for (var K in newStatTable) {
        var teamName        = newStatTable[K][0];
        var teamRank        = newStatTable[K][1];
        var teamStats       = rankingsTable[teamName]  ||  new Array (numPositions);

        teamStats[columnIdx]    = teamRank;
        rankingsTable[teamName] = teamStats;
    }

    if (numPagesFetched === numPositions) {
        displayFinalResult ();
    }
}

function displayFinalResult () {
    //Sort team name
    var sortedTeamNames = Object.keys (rankingsTable).sort ( function (zA, zB) {
        return zA.localeCompare (zB);
    } );

    //Store team name and rank array in a single array
    for (var J in sortedTeamNames) {
        var teamName    = sortedTeamNames[J];
        if (rankingsTable.hasOwnProperty (teamName) ) {
            final[teamName] = rankingsTable[teamName]
        }
    }

    //Save array to browser
    GM_setValue (tableName,  JSON.stringify (final) );
    displayResults(final)
}

function getColor(rank) {
    if (1 <= rank && rank <= 10) color = "F-rank-good"; //Green
    else if (11 <= rank && rank <= 22) color = "F-rank-neutral"; //Yellow
    else if (23 <= rank && rank <= 32) color = "F-rank-bad"; //Red
    return color;
}

function displayResults(result) {

    //Get saved results
    var myList      = {};
    var myListObj   = GM_getValue (tableName,  "");
    if (myListObj) {
        myList      = JSON.parse (myListObj);
    }
    //Check if we have already fetched results for the day
    if (typeof result === 'undefined') { result = myList; console.log("Loading pre-loaded data");}
    function delinkChangeStat (jNode) {
        var raw = jNode[0].innerHTML
        //console.log(raw)
        if ((player = raw.match(/<span class="Fz-xxs">.*? - (\w+)/)) && (opp = raw.match(/(?:vs|\@) (\w+)/))) {
            var playerIndex = playerPositions.indexOf(player[1])
            if( playerIndex != -1) { 
                var rank = result[opp[1]][playerIndex];
                console.log(opp[1] + " gives up the #" + rank + " points to the " + player[1] + " position");
                jNode.html(jNode.html().replace(opp[1] + "</a>", "<span class='" + getColor(rank) + "'>" + opp[1] + " - " + rank + "</span></a>"))
            }
        }
    }
    
    function opponentsPage (jNode) {
        var posA = jNode[0].querySelectorAll('span.Fz-xxs:not(.ysf-player-status):not(.Px-xxs)');
        for(i=0; i<posA.length; i++) {
            var pos = posA[i].innerHTML.split(" ").slice(-1)[0] //QB
            var oppA = jNode[0].querySelectorAll('.P-xs');
            for(i=0; i<oppA.length; i++) {
                var opp = oppA[i].innerText.trim() //Opposing team without @
                var playerIndex = playerPositions.indexOf(pos)
                var opp_without = opp.replace("@","")
                if (opp_without != "Bye") {
                    var rank = result[opp_without][playerIndex];
                    oppA[i].innerHTML = "<span class='" + getColor(rank) + "'>" + oppA[i].innerHTML + " - " + rank + "</span></a>"
                }
                else {
                    oppA[i].innerHTML = "<b>" + oppA[i].innerHTML + "</b>";
                }
            }
        }


    }
    waitForKeyElements (".Mx-a", delinkChangeStat);
    waitForKeyElements (".Ov-h", delinkChangeStat);
    waitForKeyElements ("tbody > tr.editable:not(.empty-bench)", opponentsPage);
}

// That's it!