// ==UserScript==
// @name           Webmaster Tools Nofollow Checker
// @namespace      http://geeklad.com
// @description    This script will check external links to see if they are nofollow links.
// @include        https://www.google.com/webmasters/tools/externallinks*bplink=*
// ==/UserScript==

// Register menu commands
GM_registerMenuCommand("Delete Nofollow Rows", function() {
  GM_setValue("deletenofollow", confirm("Remove nofollow rows?"));
});
GM_registerMenuCommand("Delete Link not Found Rows", function() {
  GM_setValue("deletenolink", confirm("Remove rows with missing links?"));
});

// Define the global variables
var siteurl = document.body.innerHTML.match(/Find link details for: ([^\n]*)/)[1];
var datatable = document.getElementById("sectionContent").getElementsByTagName("table")[1];
var subpage = datatable.getElementsByTagName("tr")[0].getElementsByTagName("input")[0].value;
var subpageurl = siteurl + subpage;

// Pagerank functions
// Code for  GooglePR, googleCH,  myfmod, c32to8bit, exclude, strord, mix, zeroFill, and hexdec was borrowed from the SEO Link Analysis Firefox extension
// Visit http://yoast.com/seo-tools/link-analysis/ for more info
function GooglePR(url, row) {
	var url1 = "info:"+url;
	var url2 = exclude( url ).replace( /_/, "%5F" );
	var ch = strord(url1);
	var chSum = googleCH(ch);
	var newCh = googleNewCh(chSum);
	var term1 = /^http:/;
	var term2 = /^http:\/\/.*google\..*\/(search|images|groups|news).*/;
	var term3 = /^http:\/\/.*\..*/;
	var myURL = "http://toolbarqueries.google.com/search?client=navclient-auto&ch=" + "6" + newCh + "&ie=UTF-8&oe=UTF-8&features=Rank&q=info:" +url2;
	
	GM_xmlhttpRequest({
		method: 'GET',
		url: myURL,
		headers: {
			'User-agent': 'Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)',
			'Accept': 'application/atom+xml,application/xml,text/xml',
		},
		onload: function(responseDetails) {
			var temp =	responseDetails.responseText;
			var temp1 = temp.match(/Rank_.*?:.*?:(\d+)/i);
			var rank = (temp1) ? temp1[1] : "-";
			row.innerHTML = row.innerHTML.replace("Checking PR...", rank);
		}
	});
}
 
function googleCH( url ) {
	var init = 0xE6359A60;
	var length = url.length;
	var a = 0x9E3779B9;
	var b = 0x9E3779B9;
	var c = 0xE6359A60;
	var k = 0;
	var len = length;
	var mixo = new Array();

	while( len >= 12 ) {
	   a += (url[k+0] +(url[k+1]<<8) +(url[k+2]<<16) +(url[k+3]<<24));
	   b += (url[k+4] +(url[k+5]<<8) +(url[k+6]<<16) +(url[k+7]<<24));
	   c += (url[k+8] +(url[k+9]<<8) +(url[k+10]<<16)+(url[k+11]<<24));
	   mixo = mix(a,b,c);
	   a = mixo[0]; b = mixo[1]; c = mixo[2];
	   k += 12;
	   len -= 12;
	}
	c += length;
	switch( len ) {
		case 11:
			c += url[k+10]<<24;
		case 10:
			c+=url[k+9]<<16;
		case 9 :
			c+=url[k+8]<<8;
		case 8 :
			b+=(url[k+7]<<24);
		case 7 :
			b+=(url[k+6]<<16);
		case 6 :
			b+=(url[k+5]<<8);
		case 5 :
			b+=(url[k+4]);
		case 4 :
			a+=(url[k+3]<<24);
		case 3 :
			a+=(url[k+2]<<16);
		case 2 :
			a+=(url[k+1]<<8);
		case 1 :
			a+=(url[k+0]);
	}
	mixo = mix( a, b, c );
	if( mixo[2] < 0 ) {
		return ( 0x100000000 + mixo[2] );
	} else {
		return mixo[2];
	}
}

function googleNewCh(ch ) {
	ch = ( ( ( ch / 7 ) << 2 ) | ( ( myfmod( ch,13 ) ) & 7 ) );
	prbuf = new Array();
	prbuf[0] = ch;
	for( i = 1; i < 20; i++ ) {
		prbuf[i] = prbuf[i-1] - 9;
	}
	ch = googleCH(c32to8bit( prbuf ), 80 );
	return ch;
}

function myfmod( x, y ) {
	var i = Math.floor( x / y );
	return ( x - i * y );
}

function c32to8bit( arr32 ) {
	var arr8 = new Array();
	
	for( i = 0; i < arr32.length; i++ ) {
		for( bitOrder = i * 4; bitOrder <= i * 4 + 3; bitOrder++ ) {
			arr8[bitOrder] = arr32[i] & 255;
			arr32[i] = zeroFill( arr32[i], 8 );       
		}
	}
	return arr8;
}
	 
function exclude( url ) {
	return escape(url).replace(/\+/g, '%2B').replace(/\"/g, '%22').replace(/\'/g, '%27');
}

function strord(string) {
	var result = new Array();
	for(i = 0; i < string.length; i++ ) {
		result[i] = string[i].charCodeAt( 0 );
	}
	return result;
}	

function mix( a, b, c ) {
	a -= b; a -= c; a ^= (zeroFill( c, 13 ) );
	b -= c; b -= a; b ^= ( a << 8 );
	c -= a; c -= b; c ^= (zeroFill( b, 13 ) );
	a -= b; a -= c; a ^= (zeroFill( c, 12 ) );
	b -= c; b -= a; b ^= ( a << 16);
	c -= a; c -= b; c ^= (zeroFill( b, 5 ) );
	a -= b; a -= c; a ^= (zeroFill( c, 3 ) );
	b -= c; b -= a; b ^= ( a << 10);
	c -= a; c -= b; c ^= (zeroFill( b, 15 ) );
	var ret = new Array( (a), (b), (c) );
	return ret;
}

function zeroFill( a, b ) {
	var z = hexdec( 80000000 );
	if( z & a ) {
		a = a >> 1;
		a &= ~z;
		a |= 0x40000000;
		a = a >> ( b - 1 );
	}
	else {
		a = a >> b;
	}
	return (a);
 }

function hexdec( str ) {
	return parseInt( str, 16 );
}

// Function for checking links
function checkNoFollow(page, link, row) {
	// Display loading message
	row.innerHTML += "<td style=\"text-align: center\">Checking Link...</td><td style=\"text-align: center\">Checking PR...</td>";
	GM_xmlhttpRequest({
		method: "GET",
		url: link,
		onload: function (response) {
			// Strip the trailing slash on the subpage URL if there is one
			if(page.substring(page.length-1, page.length) == "/")
				page = page.substring(0, page.length-1);

			try {
				// Get all of the anchors with the subpage URL
				anchors = response.responseText.match("<a (?:(?:(?!" + page + ")[^>])*" + page + ")[^>]*>", "gi").join("");
				if(anchors.match(/nofollow/i)) {
					nofollow = "Yes";
					// Check to see if we delete the row
					if (GM_getValue("deletenofollow", true)) {
						row.parentNode.removeChild(row);
						return;
					}
				} else
					nofollow = "No";
			}
			catch(err) {
				// If the subpage URL isn't found, the join method will cause it to blow up, so we know the link wasn't found
				nofollow = "Link not found";
				// Check to see if we delete the row
				if (GM_getValue("deletenolink", true)) {
					row.parentNode.removeChild(row);
					return;
				}
			}
			
			// Output the nofollow status
			row.innerHTML = row.innerHTML.replace("Checking Link...", nofollow);
		}
	});
}

// Add the new column labels
datatable.getElementsByTagName("tr")[1].innerHTML += "<td style=\"text-align: center;\">Nofollow<sup><a href=\"#\" onclick=\"javascript:alert(\'A Yes in this column indicates the link is nofollow, and therefore DOES NOT contribute to PageRank.\')\" style=\"text-decoration: none\">*</a></sup></td><td style=\"text-align: center;\">PageRank</td>";
datatable.getElementsByTagName("tr")[0].getElementsByTagName("td")[1].colSpan = 3;
datatable.getElementsByTagName("tr")[datatable.rows.length-1].getElementsByTagName("td")[2].colSpan = 4;

// Add the new columns
for each(row in datatable.getElementsByTagName("tr")) {
	if (row.rowIndex > 1) {
		linkurl = row.getElementsByTagName("a")[0].href;
		checkNoFollow(subpageurl, linkurl, row);
		GooglePR(linkurl, row);
	}
}