/* 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]]