Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// User:Quarl/alexafy.js - adds "alexa" links to external links

// requires addlilink.js, util.js

// quarl 2005-01-10 new AJAX version that annotates page asynchronously with rank

// I tried to create a version that automatically downloads the Alexa rank and annotates the page, but I think it's disallowed because it's not from the same domain.  So it would be impossible without a server-side helper script on en.wikipedia.org.

// based on http://en.wikipedia.org/wiki/User:Matthewmayer/monobook.js

//add Alexafy link to toolbar
function addToolboxAlexafy() { 
    addToolboxLink('javascript:alexafyLinks()','Alexa-fy links','alexafyLinks')
}

function alexafyWhitelistedP(url) {
    if (url.match(/wikipedia.org/)) return true;
    return false;
}

function alexafyLinks() {
    var content=document.getElementById('content');
    var externallinks=getElementsByClass('external',content,'a');
    for (i in externallinks) {
        var alink=externallinks[i];
        if (alexafyWhitelistedP(alink.href)) continue;

        alexafy_asyncAnnotateLink(alink);
    }
}

function alexafy_asyncAnnotateLink(alink) {
    var alexaUrl = makeAlexaTrafficUrl(alink.href);
    var dnode = document.createElement('span');
    dnode.innerHTML = ' [<a href="'+alexaUrl+'">Alexa</a>]';
    add_after(alink, dnode);

    // XXX this doesn't work because of permissions.  see top.
    //alexafy_asyncGetRank(dnode,alexaUrl);
}

function makeAlexaTrafficUrl(url) {
    return 'http://www.alexa.com/data/details/traffic_details?q=&url=' + url;
}

function alexafy_asyncGetRank(dnode, alexaUrl) {
    var req = new XMLHttpRequest();
    req.dnode = dnode;
    // using onload instead of onreadystatechange allows multiple asynchronous requests
    req.onload = alexafy_asyncReqCont;
    req.open("GET", alexaUrl, true);
    req.send(null);
}

function alexafy_asyncReqCont(event) {
    req = event.target;
    if (req.readyState!=4) return;
    if (req.status == 200) {
        if (req.responseText.match(/<span.*?Traffic Rank for\t*(.*?):<\/span><span.*?-->([0-9,]+)<\/span>/)) {
            var domain = RegExp.$1;
            var rank = RegExp.$2;
            alexafy_annotateDoc(req.dnode, domain, rank);
            return;
         //<span class="body"> Traffic Rank for  example.org:</span><span class="descBold">	&nbsp;<!--Did you know? Alexa offers this data programmatically.  Visit http://webservices.amazon.com/ for more information about the Alexa Web Information Service.-->123,456</span>
        }
        if (req.responseText.match(/<span.*?Traffic Rank for.*?No Data/)) {
            //<span class="body"> Traffic Rank for :</span>&nbsp;No Data<br>
            alexafy_annotateDoc(req.dnode, null, 'No data');
            return;
        }
    }
    alexafy_annotateDoc(req.dnode, null, 'Error');
}

function alexafy_annotateDoc(dnode, domain, rank)
{
    var msg;
    if (rank == 'Error') {
        msg = "couldn't get Alexa rank";
    } else if (rank == 'No data') {
        msg = "no traffic data";
    } else {
        msg = "traffic rank for "+domain+" is "+rank;
    }
    dnode.innerHTML = dnode.innerHTML.substr(0,dnode.innerHTML.length-1) + msg + "]";
}

addOnloadHook(addToolboxAlexafy);