By Cherokee
Has no other scripts.
// ESPN 4 factors boxscore
// version 0.3
// 2007-10-31
//
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script that adds team 4-factors stats
// to ESPN NBA boxscores
//
// 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 "ESPN4Factors", and click Uninstall.
//
//
// ==UserScript==
// @name ESPN4Factors
// @description Adds team 4-factors stats to ESPN NBA boxscores
// @include http://*.espn.go.com/nba/boxscore?gameId=*
// ==/UserScript==
/* BEGIN LICENSE BLOCK
Copyright (C) 2007 cherokee_acb
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You can download a copy of the GNU General Public License at
http://diveintomark.org/projects/greasemonkey/COPYING
or get a free printed copy by writing to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
END LICENSE BLOCK */
doc = window.document;
var live = 0;
// Read team names
var teamCells = doc.evaluate("//td[@class='team']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var awayTeam = teamCells.snapshotItem(1).firstChild.textContent;
var homeTeam = teamCells.snapshotItem(2).firstChild.textContent;
// Get team stats
var colheads = doc.evaluate("//td[@colspan='2']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// First, the away team
var fgcA = colheads.snapshotItem(0).nextSibling;
if (fgcA.textContent.match(/FGM/)) {
fgcA = colheads.snapshotItem(1).nextSibling;
live = 1;
}
var fgmA = parseInt(fgcA.textContent.substring(0, fgcA.textContent.indexOf("-")));
var fgaA = parseInt(fgcA.textContent.substring(fgcA.textContent.indexOf("-")+1));
var p3cA = fgcA.nextSibling;
var p3mA = parseInt(p3cA.textContent.substring(0, p3cA.textContent.indexOf("-")));
var p3aA = parseInt(p3cA.textContent.substring(p3cA.textContent.indexOf("-")+1));
var ftcA = p3cA.nextSibling;
var ftmA = parseInt(ftcA.textContent.substring(0, ftcA.textContent.indexOf("-")));
var ftaA = parseInt(ftcA.textContent.substring(ftcA.textContent.indexOf("-")+1));
var orcA = ftcA.nextSibling;
var drcA = orcA.nextSibling;
var orA = parseInt(orcA.textContent);
var drA = parseInt(drcA.textContent);
if (live) {
drA = drA-orA;
}
// Now the home team
var fgcH = colheads.snapshotItem(2).nextSibling;
if (live) {
fgcH = colheads.snapshotItem(4).nextSibling;
}
var fgmH = parseInt(fgcH.textContent.substring(0, fgcH.textContent.indexOf("-")));
var fgaH = parseInt(fgcH.textContent.substring(fgcH.textContent.indexOf("-")+1));
var p3cH = fgcH.nextSibling;
var p3mH = parseInt(p3cH.textContent.substring(0, p3cH.textContent.indexOf("-")));
var p3aH = parseInt(p3cH.textContent.substring(p3cH.textContent.indexOf("-")+1));
var ftcH = p3cH.nextSibling;
var ftmH = parseInt(ftcH.textContent.substring(0, ftcH.textContent.indexOf("-")));
var ftaH = parseInt(ftcH.textContent.substring(ftcH.textContent.indexOf("-")+1));
var orcH = ftcH.nextSibling;
var drcH = orcH.nextSibling;
var orH = parseInt(orcH.textContent);
var drH = parseInt(drcH.textContent);
if (live) {
drH = drH-orH;
}
// We use total team turnovers, instead of the sum of player turnovers in the boxscore
var toCells = doc.evaluate("//td[@colspan='9']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (live) {
toCells = doc.evaluate("//td[@colspan='8']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
}
var toA = parseInt(toCells.snapshotItem(0).textContent.substr(19,2));
var toH = parseInt(toCells.snapshotItem(1).textContent.substr(19,2));
// Get minutes played
var clock = doc.evaluate("//div[@class='game-status']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
var min = 48;
if (clock.textContent.match(/Final/)) {
if (clock.textContent.match(/OT/)) {
if (clock.textContent.charAt(10) == 'O' ) {
min = 53;
}
else {
min = 48 + 5*clock.textContent.charAt(10);
}
}
}
else if (clock.textContent.match(/Halftime/)) {
min = 24;
}
else {
delimIndex = clock.textContent.indexOf(":");
min = 11-parseInt(clock.textContent.substr(delimIndex-2, 2));
var secs = 60-parseInt(clock.textContent.substr(delimIndex+1, 2));
var quarter = parseInt(clock.textContent.substr(delimIndex+5, 1));
min += secs/60 + 12*(quarter-1);
}
// For possessions, we use the Hollinger formula with a 0.976 correction factor.
// Then we average both team estimates, and round to the nearest integer
var possA = fgaA + 0.44*ftaA - orA + toA;
var possH = fgaH + 0.44*ftaH - orH + toH;
var poss = 0.976*(possH + possA)/2;
poss = poss.toFixed(0);
var pace = 48*poss/min;
// Now, we compute efficiency and the four factors
var effA = 100*(2*fgmA + p3mA + ftmA)/poss;
var efgA = 100*(fgmA + 0.5*p3mA)/fgaA;
var ftrA = 100*ftmA/fgaA;
var orpA = 100*orA/(orA+drH);
var torA = 100*toA/poss;
var effH = 100*(2*fgmH + p3mH + ftmH)/poss;
var efgH = 100*(fgmH + 0.5*p3mH)/fgaH;
var ftrH = 100*ftmH/fgaH;
var orpH = 100*orH/(orH+drA);
var torH = 100*toH/poss;
// Finally, we create the table, rows and cells where data will be displayed.
// Format is the same as in the per-quarter score table
var tdAux;
var bold;
var cellWidth = '50px';
var factors = doc.createElement("table");
// factors.setAttribute('align','center');
var header = doc.createElement("tr");
header.setAttribute('align', 'center');
tdAux = doc.createElement("td");
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
if (min == 48) {
under.textContent = "Pace";
tdAux.setAttribute('width',cellWidth );
}
else {
under.textContent = "Pace (Poss)";
tdAux.setAttribute('width',2*cellWidth );
}
tdAux.appendChild(under);
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
under.textContent = "Eff";
tdAux.appendChild(under);
tdAux.setAttribute('width',cellWidth );
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
under.textContent = "eFG";
tdAux.appendChild(under);
tdAux.setAttribute('width',cellWidth );
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
under.textContent = "FT/FG";
tdAux.appendChild(under);
tdAux.setAttribute('width',cellWidth );
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
under.textContent = "OREB%";
tdAux.appendChild(under);
tdAux.setAttribute('width',cellWidth );
header.appendChild(tdAux);
tdAux = doc.createElement("td");
under = doc.createElement("u");
under.textContent = "TOr";
tdAux.appendChild(under);
tdAux.setAttribute('width',cellWidth );
header.appendChild(tdAux);
var aRow = doc.createElement("tr");
aRow.setAttribute('align', 'center');
tdAux = doc.createElement("td");
tdAux.setAttribute('align', 'left');
tdAux.setAttribute('class','team');
bold = doc.createElement("b");
bold.textContent = awayTeam;
tdAux.appendChild(bold);
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
if (min == 48) {
tdAux.textContent = pace.toFixed(1);
}
else {
tdAux.textContent = pace.toFixed(1) + " (" + poss + ")";
}
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = effA.toFixed(1);
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = efgA.toFixed(1) + "%";
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = ftrA.toFixed(1);
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = orpA.toFixed(1);
aRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = torA.toFixed(1);
aRow.appendChild(tdAux);
var hRow = doc.createElement("tr");
hRow.setAttribute('align', 'center');
tdAux = doc.createElement("td");
tdAux.setAttribute('align', 'left');
bold = doc.createElement("b");
bold.textContent = homeTeam;
tdAux.appendChild(bold);
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
// tdAux.textContent = pace.toFixed(1);
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = effH.toFixed(1);
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = efgH.toFixed(1) + "%";
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = ftrH.toFixed(1);
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = orpH.toFixed(1);
hRow.appendChild(tdAux);
tdAux = doc.createElement("td");
tdAux.textContent = torH.toFixed(1);
hRow.appendChild(tdAux);
factors.appendChild(header);
factors.appendChild(aRow);
factors.appendChild(hRow);
// We insert the 4 factors table into a <div> element, and this div just before the boxscore table
var factorsDiv = doc.createElement("div");
factorsDiv.setAttribute('align','center');
factorsDiv.appendChild(factors);
var tabberNodes = doc.evaluate("//div[@class='gp-body']", doc.body, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var tabber = tabberNodes.snapshotItem(0);
tabber.insertBefore(factorsDiv, tabber.firstChild);
//
// ChangeLog
// 2007-03-07 - 0.1 - First draft
// 2007-03-10 - 0.2 - Added support of live boxscores
// 2007-10-31 - 0.3 - Updated to 2007-08 format