Jump to content

User:FlightTime/vector.js

From Simple English Wikipedia, the free encyclopedia
Revision as of 14:41, 30 May 2010 by FlightTime (talk | changes) (change script to indentify disambig links (hope))

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Copied from [[en:User:Anomie/linkclassifier.js]] */


/* If you want to use this script, simply add the following line to your [[Special:Mypage/monobook.js]]:

importScript('User:Anomie/util.js');
importScript('User:Anomie/linkclassifier.js'); // Linkback: [[User:Anomie/linkclassifier.js]]

* (Please keep the comment so I can see how many people use this). You will also want to
* add some CSS classes, such as those at [[User:Anomie/linkclassifier.css]].
*/

/* If you want this to run "on demand" instead of on every page, set "LinkClassifierOnDemand=true" and
 * use addPortletLink() or the like to add a button calling LinkClassifier.onDemand().
 */

importScriptURI('http://en.wikipedia.org/w/index.php?title=User:Anomie/util.js&action=raw&ctype=text/javascript');  // for backwards compat


var LinkClassifier={
    /* This array lists "for deletion" categories */
    cats:{
        deletion:[
            'Category:All articles proposed for deletion',
            'Category:All books proposed for deletion',
            'Category:All disputed non-free Wikipedia files',
            'Category:All orphaned non-free use Wikipedia files',
            'Category:All replaceable non-free use Wikipedia files',
            'Category:All Wikipedia files with no copyright tag',
            'Category:All Wikipedia files with no non-free use rationale',
            'Category:All Wikipedia files with unknown copyright status',
            'Category:All Wikipedia files with unknown source',
            'Category:Articles for deletion',
            'Category:Articles on deletion review',
            'Category:Candidates for speedy deletion',
            'Category:Candidates for undeletion',
            'Category:Categories for conversion',
            'Category:Categories for deletion',
            'Category:Categories for listifying',
            'Category:Categories for merging',
            'Category:Categories for renaming',
            'Category:Categories for speedy renaming',
            'Category:Categories to be listified then deleted',
            'Category:Miscellaneous pages for deletion',
            'Category:Pending deletions',
            'Category:Redirects for discussion',
            'Category:Stub categories for deletion',
            'Category:Stub template deletion candidates',
            'Category:User categories for discussion',
            'Category:Wikipedia deprecated and orphaned templates',
            'Category:Wikipedia files for deletion',
            'Category:Wikipedia files with unknown source for deletion in dispute',
            'Category:Wikipedia templates for deletion'
        ].sort(),
        disambiguation:[
            'Category:Disambiguation'
        ].sort(),
        'featured-content':[
            'Category:Featured articles',
            'Category:Featured lists',
            'Category:Featured pictures',
            'Category:Featured sounds',
            'Category:Featured videos',
            'Category:Featured portals'
        ].sort(),
        'spoken-articles':[
            'Category:Spoken articles'
        ].sort(),
        stubcls:/^Category:.* stubs$/,
        'nonfree-media':[
            'Category:All non-free media'
        ].sort()
    },
 
    callback:function(r, cc){
        if(!r.query) throw new Error('Bad response');
        if(r['query-continue']){
            for(var k in r['query-continue']){
                for(var k2 in r['query-continue'][k]){
                    cc[k2]=r['query-continue'][k][k2];
                }
            }
            api(cc, arguments.callee);
        }
        r=r.query;

        var a=document.getElementById('wikiPreview');
        if(!a) a=document.getElementById('bodyContent');
        if(!a) throw new Error('Huh? No body content?');
        a=a.getElementsByTagName('A');
        if(a.length==0) return;

        var redir={};
        if(r.redirects) for(var i=r.redirects.length-1; i>=0; i--){
            redir[r.redirects[i].from]=r.redirects[i].to;
        }
        var cats={};
        var missing={};
        var prot={};
        if(r.pages) for(var i in r.pages){
            missing[r.pages[i].title]=(typeof(r.pages[i].missing)!='undefined');
            if(typeof(r.pages[i].categories)!='undefined'){
                cats[r.pages[i].title]=r.pages[i].categories.map(function(a){ return a.title; }).sort();
            }
            if(typeof(r.pages[i].protection)!='undefined'){
                prot[r.pages[i].title]=[];
                var x={};
                for(var j=r.pages[i].protection.length-1; j>=0; j--){
                    var p='protection-'+r.pages[i].protection[j].type+'-'+r.pages[i].protection[j].level;
                    if(typeof(x[p])=='undefined'){
                        x[p]=1;
                        prot[r.pages[i].title].push(p);
                    }
                    if(r.pages[i].protection[j].expiry=='infinity'){
                        p+='-indef';
                        if(typeof(x[p])=='undefined'){
                            x[p]=1;
                            prot[r.pages[i].title].push(p);
                        }
                    }
                }
            }
        }
        Array.forEach(a, function(a){
            if(typeof(a.wikipage)=='undefined') return;
            if(typeof(redir[a.wikipage])!='undefined'){
                addClass(a,'redirect');
                a.wikipage=redir[a.wikipage];
                a.title=a.wikipage;
                if(a.wikipage==(wgCanonicalNamespace?wgCanonicalNamespace+':':'')+wgTitle)
                    addClass(a,'self-redirect');
                if(missing[a.wikipage])
                    addClass(a,'broken-redirect');
            }
            var m=a.href.match(/#.*/);
            if(m){
                a.title=a.title.replace(/#.*/,'')+m[0].replace(/_/g,' ').replace(/\.([0-9A-F][0-9A-F])/gi, function(x,n){ return String.fromCharCode(parseInt(n,16)); });
            }
            if(typeof(prot[a.wikipage])!='undefined'){
                for(var j=prot[a.wikipage].length-1; j>=0; j--)
                    addClass(a,prot[a.wikipage][j]);
            }
            if(typeof(cats[a.wikipage])!='undefined'){
                var c1=cats[a.wikipage];
                for(var cls in LinkClassifier.cats){
                    var i1=c1.length-1;
                    var c2=LinkClassifier.cats[cls];
                    if(c2 instanceof RegExp){
                        while(i1>=0){
                            if(c2.test(c1[i1])){
                                addClass(a,cls);
                                break;
                            }
                            i1--;
                        }
                    } else {
                        var i2=c2.length-1;
                        while(i1>=0 && i2>=0){
                            if(c1[i1]==c2[i2]){
                                addClass(a,cls);
                                break;
                            }
                            (c1[i1]>c2[i2])?--i1:--i2;
                        }
                    }
                }
            }
            if(r.protection) for(var i=r.protection.length-1; i>=0; i--){
            }
        });
    },

    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;
    },

    classifyChildren:function(node){
        var a=node.getElementsByTagName('A');
        if(a.length==0) return;
        var self=LinkClassifier.getPageName(location.href);
        a=Array.map(a, function(a){
            a.wikipage='';
            if(/(^|\s)(external|extiw)(\s|$)/.test(a.className)) return '';
            if(!/(^|\s)(image)(\s|$)/.test(a.className)) a.className+=" nonimage";
            a.wikipage=LinkClassifier.getPageName(a.href);
            if(a.wikipage==self) a.wikipage='';
            return a.wikipage;
        }).sort().filter(function(e,i,a){
            return e!=='' && (i==0 || a[i-1]!==e);
        });
        while(a.length>0){
            api({action:'query', titles:a.splice(0,50), prop:'categories|info', redirects:1, cllimit:'max', inprop:'protection'}, LinkClassifier.callback);
        }
    },
 
    onLoad:function(){
        if(window.AJAXPreview) window.AJAXPreview.AddOnLoadHook(LinkClassifier.classifyChildren);
        LinkClassifier.onDemand();
    },
 
    onDemand:function(){
        var node=document.getElementById('wikiPreview');
        if(!node) node=document.getElementById('bodyContent');
        if(node) LinkClassifier.classifyChildren(node);
    }
};

if(!window.LinkClassifierOnDemand){
    if(doneOnloadHook) LinkClassifier.onLoad(); //if imported dynamically
    else addOnloadHook(LinkClassifier.onLoad);
}





/* Various random utility functions I find useful. If for some reason you want to
 * use these in your code, the following line will import them for you:

importScript('User:Anomie/util.js'); // Linkback: [[User:Anomie/util.js]]
 
 * (Please keep the comment so I can see how many people use this).
 */

function jsondecode(v){
    try {
        return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u\n\r\t]/.test(v.replace(/"(\\.|[^\x22\\])*"/g,''))) && eval('('+v+')');
    } catch(e){
        return null;
    }
}

if(!Number.prototype.toHex) Number.prototype.toHex = function(p){
        var s=this.toString(16);
        var i=s.indexOf('.');
        if(i<0) i=s.length;
        if(typeof(p)!='undefined') for(p-=i; p>0; p--){
                s='0'+s;
        }
        return s;
}
if(!Number.toHex) Number.toHex = function(n,p){
	return Number(n).toHex(p);
}

if(!RegExp.quote){
    RegExp.quote = function(s){
        return s.replace(/[^\t !\x22#%&\x27,:;<=>@_`~a-z0-9]/ig, RegExp.quote.$replacer);
    }
    RegExp.quote.$replacer = function(c){
        c=c.charCodeAt(0);
        return '\\u'+c.toHex(4);
    }
}

function api(p, cb){
    var uri=wgServer+wgScriptPath+'/api.php';
    var data='format=json';
    for(var k in p){
        var v=p[k];
        if(typeof(v)=='object' && (v instanceof Array))
            v=v.map(encodeURIComponent).join('|');
        else
            v=encodeURIComponent(v);
        data+='&'+encodeURIComponent(k)+'='+v;
    }
    
    var x = sajax_init_object();
    if(!x) return false;

    if(typeof(cb)=='function'){
        x.open('POST', uri, true);
        x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        x.onreadystatechange=function(){
            if(x.readyState!=4) return;
            var r=jsondecode(x.responseText);
            if(!r) throw new Error("Could not parse response");
            cb(r, p);
        };
        x.send(data);
        return true;
    } else {
        x.open('POST', uri, false);
        x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        x.send(data);
        var r=jsondecode(x.responseText);
        if(!r) throw new Error("Could not parse response");
        return r;
    }
}

function rawpage(pg, cb){
    var uri=wgServer+wgScriptPath+'/index.php?action=raw&title='+encodeURIComponent(pg);
    
    var x = sajax_init_object();
    if(!x) return false;

    if(typeof(cb)=='function'){
        x.open('GET', uri, true);
        x.onreadystatechange=function(){
            if(x.readyState!=4) return;
            cb(x.responseText);
        };
        x.send(null);
        return true;
    } else {
        x.open('GET', uri, false);
        x.send(null);
        return x.responseText;
    }
}

function isClass(n, c){
	return n.className.match(new RegExp('(^|\\s)'+c+'(\\s|$)'));
}
function addClass(n, c){
	if(!isClass(n,c)) n.className=(n.className=='')?c:(n.className+' '+c);
}
function delClass(n, c){
	var cl=n.className;
	cl=cl.replace(new RegExp('(^|\\s)'+c+'(\\s|$)', 'g'), ' ');
	cl=cl.replace(/\s\s+/g, ' ').replace(/^\s+|\s+$/g, '');
	if(n.className!=cl) n.className=cl;
}

if(!Array.prototype.map) Array.prototype.map=function(callback, thisObject){
        var l=this.length;
        var a=[];
        if(typeof(thisObject)=='undefined' || thisObject===null){
                for(var i=0;i<l;i++){
                        a[i]=callback(this[i],i,this);
                }
        } else {
                for(var i=0;i<l;i++){
                        a[i]=callback.call(thisObject,this[i],i,this);
                }
        }
        return a;
}
if(!Array.map) Array.map=function(obj, callback, thisObject){
        return Array.prototype.map.call(obj, callback, thisObject);
}

if(!Array.prototype.forEach) Array.prototype.forEach=function(callback, thisObject){
	var l=this.length;
	if(typeof(thisObject)=='undefined' || thisObject===null){
		for(var i=0;i<l;i++){
			callback(this[i],i,this);
		}
	} else {
		for(var i=0;i<l;i++){
			callback.call(thisObject,this[i],i,this);
		}
	}
}
if(!Array.forEach) Array.forEach=function(obj, callback, thisObject){
	return Array.prototype.forEach.call(obj, callback, thisObject);
}

if(!Array.prototype.filter) Array.prototype.filter=function(callback, thisObject){
	var l=this.length;
	var a=[];
	if(typeof(thisObject)=='undefined' || thisObject===null){
		for(var i=0;i<l;i++){
			if(callback(this[i],i,this)) a.push(this[i]);
		}
	} else {
		for(var i=0;i<l;i++){
			if(callback.call(thisObject,this[i],i,this)) a.push(this[i]);
		}
	}
	return a;
}
if(!Array.filter) Array.filter=function(obj, callback, thisObject){
	return Array.prototype.filter.call(obj, callback, thisObject);
}