User:N8wilson/AQFetcher.js

/* This script will classify as many links as possible and assign CSS classes

accordingly. See the complete script documentation for usage and more details.

Key acknowledgement goes to User:Anomie whose script (User:Anomie/linkclassifier.js)

was used as an initial template structure to get up an running quickly with MW api. Go

check it out if you're interested in a lot more ways to classify and color various MW links.

  • /

var AQFetcher={

articleClasses: { 'FA':[], 'GA':[], 'A':[], 'B':[], 'C':[], 'Start':[], 'Stub':[], 'Unclassified':[] },

callback:function(r, sts, xhr){

if(!r || !r.query) {

if(typeof(window.console)=='undefined' || typeof(window.console.error)!='function')

mw.log.error(new Error('Bad response'));

window.console.error("Bad response", r);

return;

}

if(r['query-continue']){

var cc=this.rawdata;

for(var k in r['query-continue']){

for(var k2 in r['query-continue'][k]){

cc[k2]=r['query-continue'][k][k2];

}

}

$.ajax({

url:mw.util.wikiScript('api'),

dataType:'json',

type:'POST',

data:cc,

rawdata:cc,

success:arguments.callee,

error:function(xhr,textStatus,errorThrown){

mw.log.error(new Error('AJAX error: '+textStatus+' '+errorThrown));

}

});

}

r=r.query;

var a=document.getElementById('wikiPreview');

if(!a) a=document.getElementById('bodyContent');

if(!a) {mw.log.error(new Error('Huh? No body content?')); return; }

a=a.getElementsByTagName('A');

if(a.length==0) return;

// Handy shortcut

var AQF = AQFetcher;

if(r.pages) for(var i in r.pages){

if(typeof(r.pages[i].categories)!='undefined'){

// If the corresponding Talk: page has appropriately-named categories we can

// match each article page to it's classification

unClassified = true;

iCat = 0;

while (unClassified && iCat < r.pages[i].categories.length) {

if (r.pages[i].categories[iCat].title!='undefined') {

if (r.pages[i].categories[iCat].title.indexOf('FA-Class') >= 0) {

AQF.articleClasses['FA'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('A-Class') >= 0) {

AQF.articleClasses['A'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('GA-Class') >= 0) {

AQF.articleClasses['GA'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('B-Class') >= 0) {

AQF.articleClasses['B'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('C-Class') >= 0) {

AQF.articleClasses['C'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('Start-Class') >= 0) {

AQF.articleClasses['Start'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

} else if (r.pages[i].categories[iCat].title.indexOf('Stub-Class') >= 0) {

AQF.articleClasses['Stub'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

unClassified = false;

}

}

iCat+=1;

}

if (unClassified) AQF.articleClasses['Unclassified'].push(AQF.getPageNameFromTalkPage(r.pages[i].title));

}

}

Array.prototype.forEach.call(a, function(a){

if(typeof(a.wikipage)=='undefined') return;

if (AQF.articleClasses['FA'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-FA');

} else if (AQF.articleClasses['GA'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-GA');

} else if (AQF.articleClasses['A'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-A');

} else if (AQF.articleClasses['B'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-B');

} else if (AQF.articleClasses['C'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-C');

} else if (AQF.articleClasses['Start'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-Start');

} else if (AQF.articleClasses['Stub'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-Stub');

} else if (AQF.articleClasses['Unclassified'].indexOf(a.wikipage) >= 0) {

$(a).addClass('AQ-Unclassified');

} else {

//$(a).addClass('AQ-Unknown'); // Having some trouble with this at the moment.

}

});

},

/* Extract the name of the WP article from the URL */

getPageName:function(url){

var m=url.match(/\/wiki\/([^?#]+)/);

if(!m) m=url.match(/\/w\/index.php\?(?:.*&)?title=([^&#]+)/);

if(!m) return '';

var t=decodeURIComponent(m[1]).replace(/_/g,' ');

if(t.substr(0,6)=='Image:') t='File:'+t.substr(6);

if(t.substr(0,11)=='Image talk:') t='File talk:'+t.substr(6);

if(t.substr(0,8)=='Special:') t='';

return t;

},

/* If given a pagename which is not in the 'Talk:' namespace, adds 'Talk:'

* and returns the name of the page in the talk namespace. Returns

* unaltered input if the provided name is already in the "Talk:" namespace */

getTalkPageFromPageName:function(name){

return (name.substr(0,5)=='Talk:') ? name : 'Talk:'+name;

},

/* If given a pagename in "Talk:" namespace, removes the namespace to return the page name

* returns unaltered input if the provided name is not in the "Talk:" namespace */

getPageNameFromTalkPage:function(name){

return (name.substr(0,5)=='Talk:') ? name.substr(5,name.length) : name;

},

classifyChildren:function(node){

mw.loader.using(['mediawiki.util','mediawiki.user'], function(){

var a=node.getElementsByTagName('A');

if(a.length==0) return;

var self=AQFetcher.getPageName(location.href);

a=Array.prototype.map.call(a, function(a){

a.wikipage='';

if(/(^|\s)(external|extiw)(\s|$)/.test(a.className)) return '';

a.wikipage=AQFetcher.getPageName(a.href);

if(a.wikipage==self) a.wikipage='';

if(a.wikipage.indexOf(':')>0) a.wikipage=''; //filter out anything not in main namespace

a.origwikipage=a.wikipage;

return AQFetcher.getTalkPageFromPageName(a.wikipage);

}).sort().filter(function(e,i,a){

return e!=='' && (i==0 || a[i-1]!==e) && e!=='Talk:';

});

// a is now a sorted array of links with wikipage attributes holding the title of talk pages

function processLinks(limit){

while(a.length>0){

var q={

format:'json',

action:'query',

titles:a.splice(0,limit).join('|'),

prop:'categories', // Only interested in Talk page categories

cllimit:'max',

rawcontinue:1

};

$.ajax({

url:mw.util.wikiScript('api'),

dataType:'json',

type:'POST',

data:q,

rawdata:q,

success:AQFetcher.callback,

error:function(xhr,textStatus,errorThrown){

mw.log.error(new Error('AJAX error: '+textStatus+' '+errorThrown));

}

});

}

}

if(a.length<=100){

// Not worth querying the API to see if the user has apihighlimits

processLinks(50);

} else {

// Note mw.user.getRights queries the API

mw.user.getRights(function(rights){

processLinks( (rights.indexOf('apihighlimits')>=0) ? 500 : 50 );

});

}

});

},

onLoad:function(){

if (mw.config.get( 'wgCanonicalNamespace' ) != "") {

console.log("Browsing in " + mw.config.get( 'wgCanonicalNamespace' )

+ " namespace so article link styles will not be applied by quality.");

return;

}

// Figure out where the article content is...

var node=document.getElementById('wikiPreview');

if(!node) node=document.getElementById('bodyContent');

if(node) AQFetcher.classifyChildren(node);

}

};

$(document).ready(AQFetcher.onLoad);

// Category:Wikipedia scripts