Jump to content

User:N8wilson/AQFetcher.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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.
/*  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]]