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);

//