Source code for bookmarklet Show Ambiguous Link Texts.
javascript:
(function(){
function linktext(node, ic)
{
function ns(nxi)
{
var str = "";
var nx = nxi;
while (nx != null)
{
if (nx.tagName == "IMG") {
if ( ic != null ) {++ic.count;}
str += (nx.hasAttribute("ALT") ? nx.alt : nx.src);
}
else if (nx.data != null
&& nx.nodeType != 8 // COMMENT_NODE
&& nx.parentNode.tagName != "SCRIPT") {
str += nx.data;
}
str += ns(nx.firstChild);
nx = nx.nextSibling;
}
return str;
}
if (node.href == null || node.href.length == 0) {return null;}
var nx = ns(node.firstChild);
return nx.replace( /\s+/mg, " ").replace( /^\s/, "" ).replace( /\s+$/, "" );
}
var lts = [];
function refs( href )
{
this.refs = [];
this.refs[ href ] = 0;
this.links = [];
}
function eD(dt)
{
var c = dt.getElementsByTagName( "A" );
for (var k = 0; k < c.length; ++k) {
var lt = linktext( c[k], null );
if ( lt != null )
{
if (c[k].title.length > 0)
{
lt = c[k].title + ": " + lt;
}
var href = c[k].href;
var b = lts[ lt ] = (lts[ lt ] != null ? lts[ lt ] : new refs(href));
b.refs[href] = href; // store href for consistency check
b.links.push( c[k] );
}
}
}
// "dIr" == "documentIterator"
function dIr(dt, f) {
function ifsr( fs )
{
for (var i = 0; i < fs.length; ++i)
{
try {
dIr(fs[i].contentDocument, fs[i]); // recursive call
}
catch (e) {
alert(e || "Unspecified error");
}
}
}
if (dt == null) {return;}
eD(dt, f);
ifsr( dt.getElementsByTagName("FRAME") );
ifsr( dt.getElementsByTagName("IFRAME") );
}
// iterate through all documents
dIr(document, null);
var duptext_count = 0, dupinstance_count = 0;
for (var lkt in lts)
{
var lt = lts[lkt];
{
var count = 0;
for (var j in lt.refs)
{
// The enumeration may show a number of non-keys (Array object properties),
// so a consistency check is necessary.
count += (lt.refs[j] == j ? 1 : 0);
}
if ( count > 1 )
{
++duptext_count;
var lcnt = lt.links.length;
dupinstance_count += lcnt;
for (var ii = 0; ii < lcnt; ++ii)
{
lt.links[ii].style.border = "thick dashed red";
lt.links[ii].title = "[" + lkt + "](" + (ii + 1) + "/" + lcnt + ")";
}
}
}
}
var st = "No ambiguous links found";
if ( duptext_count > 0 )
{
st = "Ambiguous link texts: " + duptext_count + " (" + dupinstance_count + " instances)";
}
alert(st);
}());