User:Ale jrb/Scripts/waLib2.js
Appearance
< User:Ale jrb | Scripts
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Ale jrb/Scripts/waLib2. |
/* ============================================== *\
** WikiApps2 - JavaScript Library
** for MediaWiki v1.16 and above
**
** Copyright (c) Alex Barley [[User:Ale_jrb]]
** Some rights reserved.
**
** ============================================== **
** revision: 0011 (BETA)
**
** TRACKER: [[User:Ale_jrb/Scripts]]
\* ============================================== */
// start
function wa_main () {
var me = this;
this.waa = new waa ();
this.wam = new wam ();
this.revision = 11;
this.go = function ( c ) {
if ( c !== undefined ) {
switch ( c ) {
case ':ajax': case ':api':
return me.waa;
break;
case ':dom': case ':page': case ':elems':
return false;
break;
case ':misc': case ':funcs': case ':func': case ':other':
return me.wam;
break;
default:
throw 'wa lib: undefined request on library call';
break;
}
}
}
}
// wikiapps ajax. expects syntax: wa(':api').action('id').action('id').wait(funcondone).action('id').action('id').wait(funcondone).run();
// returned container
// Action elements just add themselves to the queue. The Wait element adds a stop to the queue, and hits Execute. Execute runs
// all Actions until the stop marker with a callback of Check. Check sees if anything is still Executing, and if not, deletes
// the Stop and hits Execute again. Repeat until queue is empty, calling funcondone as required. Return data can always be
// accessed internally from wa(':api').results['id'] or wa(':ajax').results['id'].
function waa () {
// wikiapps ajax
var m = this;
if ( wgServer !== undefined ) { this.wikibase = wgServer; this.wikiapi = this.wikibase + wgScriptPath + '/api.php'; this.wikipage = this.wikibase + wgArticlePath.replace ( '$1', '' ); }
this.intqueueid = 0;
this.queue_torun = {};
this.queue_isrun = {};
this.queue_torun [ this.intqueueid ] = [];
this.queue_isrun [ this.intqueueid ] = [];
this.results = {};
this.editreq = 0; // we use this as the internal id so that editreqs without a token don't get confused with other, simultaneous, internal requests.
}
waa.prototype.exec = function ( queueid, eatstop ) {
// handles queue, creates waar objects as required and executes them.
var m = wa (':api' );
var dobreak = false;
m.killqueue = [];
// perform queue handling. If a queue is provided, we want to move all the actions on the current internal queue onto the
// user defined queue (we push them on after any that are already there, or create it if it doesn't exist). We then want to execute that queue.
// If no queue is defined (or an internal queue is defined) we'll just use that one.
if ( ( queueid === null ) || ( queueid === undefined ) ) {
queueid = m.intqueueid ++; // set the queue for this execution, and increment count for the next one
m.queue_torun [m.intqueueid] = []; m.queue_isrun [m.intqueueid] = [];
} else {
if ( m.queue_torun [queueid] === undefined ) {
m.queue_torun [queueid] = []; m.queue_isrun [queueid] = [];
m.queue_torun [queueid] = m.queue_torun [queueid].concat ( m.queue_torun [m.intqueueid] );
m.queue_isrun [queueid] = m.queue_isrun [queueid].concat ( m.queue_isrun [m.intqueueid] );
} else {
m.queue_torun [queueid] = m.queue_torun [queueid].concat ( m.queue_torun [m.intqueueid] );
m.queue_isrun [queueid] = m.queue_isrun [queueid].concat ( m.queue_isrun [m.intqueueid] );
}
m.intqueueid ++;
m.queue_torun [m.intqueueid] = []; m.queue_isrun [m.intqueueid] = [];
}
while ( m.queue_torun [queueid][0] !== undefined ) {
switch ( m.queue_torun [queueid][0][0] ) {
case 'stop':
if ( eatstop === true ) {
if ( typeof m.queue_torun [queueid][0][1] !== 'function' ) m.queue_torun [queueid][0][1] = function () {};
m.queue_torun [queueid][0][1] ();
eatstop = false;
} else { dobreak = true; }
break;
case 'command':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
if ( m.queue_torun [queueid][0][1][2] === undefined ) m.queue_torun [queueid][0][1][2] = 'GET';
var tempurl = this.wikiapi + '?' + m.queue_torun [queueid][0][1][1];
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = m.queue_torun [queueid][0][1][2];
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'token':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
var tempurl = this.wikiapi + '?format=xml&action=query&prop=info&titles=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] );
tempurl += '&intoken=' + m.queue_torun [queueid][0][1][2];
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'GET';
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'rtoken':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
var tempurl = this.wikiapi + '?format=xml&action=query&prop=revisions&titles=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] );
tempurl += '&rvprop=ids&rvlimit=1&rvtoken=rollback';
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'GET';
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'rollback':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
var tempurl = this.wikiapi;
var temppost = 'format=xml&action=rollback&user=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] );
temppost += '&title=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][2] );
temppost += '&token=' + encodeURIComponent ( m.results [ m.queue_torun [queueid][0][1][0] ]['query']['pages']['page']['revisions']['rev-attr']['rollbacktoken'] );
if ( m.queue_torun [queueid][0][1][3] ) temppost += '&summary=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][3] );
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'POST';
tempcall.postParams = temppost;
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'get':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
var tempurl = this.wikiapi + '?format=xml&action=query&prop=revisions&titles=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] );
tempurl += '&rvprop=content&rvlimit=' + m.queue_torun [queueid][0][1][2];
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'GET';
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'contribs':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
if ( m.queue_torun [queueid][0][1][2] === undefined ) m.queue_torun [queueid][0][1][2] = 10;
var tempurl = this.wikiapi + '?format=xml&action=query&list=usercontribs&uclimit=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][2] );
tempurl += '&ucuser=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] ) + '&ucprop=ids|title|timestamp|comment';
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'GET';
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'block':
this.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
if ( m.queue_torun [queueid][0][1][2].indexOf ( 'intok' ) > -1 ) {
var usetoken = m.results [ m.queue_torun [queueid][0][1][2] ]['query']['pages']['page-attr']['blocktoken'];
} else {
var usetoken = m.queue_torun [queueid][0][1][2];
}
usetoken = wa ( ':func' ).encodewiki ( usetoken );
var tempurl = this.wikiapi
var temppost = 'format=xml&action=block&user=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][1] );
temppost += '&expiry=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][3] );
temppost += '&reason=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][4] ) + '' + m.queue_torun [queueid][0][1][5];
temppost += '&token=' + usetoken;
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'POST';
tempcall.postParams = temppost;
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null;
break;
case 'edit':
// there are two cases: either there is a token, or there is an intok pointer to a token. If this is the case, this token will
// be looked up in the memory base before committing the edit.
m.queue_isrun[queueid].push ( m.queue_torun [queueid][0][1][0] );
if ( m.queue_torun [queueid][0][1][2].indexOf ( 'intok' ) > -1 ) {
var usetoken = m.results [ m.queue_torun [queueid][0][1][2] ]['query']['pages']['page-attr']['edittoken'];
} else {
var usetoken = m.queue_torun [queueid][0][1][2];
}
usetoken = wa ( ':func' ).encodewiki ( usetoken );
if ( this.queue_torun [ queueid ][0][1][5] === 'append' ) {
var text = '&appendtext=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][3] );
} else if ( this.queue_torun [ queueid ][0][1][5] === 'prepend' ) {
var text = '&prependtext=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][3] );
} else {
var text = '&text=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][3] );
}
var tempurl = this.wikiapi;
var temppost = 'format=xml&action=edit&title=' + wa ( ':func' ).encodewiki ( m.queue_torun [ queueid ][0][1][1] );
temppost += '&summary=' + wa ( ':func' ).encodewiki ( m.queue_torun [queueid][0][1][4] ) + text;
temppost += '&token=' + usetoken;
var tempcall = new waar ( m.queue_torun [queueid][0][1][0], queueid );
tempcall.requestType = 'POST';
tempcall.postParams = temppost;
tempcall.requestUrl = tempurl;
tempcall.doRequest ( m.check, queueid );
tempcall = null; tempurl = null; temppost = null;
break;
default:
throw 'wa lib: unrecognised item in chain queue; check library extensions';
break;
}
if ( dobreak === true ) break;
this.queue_torun[queueid].splice ( 0, 1 );
}
return this;
}
waa.prototype.run = function ( queueid ) {
this.exec ( queueid ); return this;
}
waa.prototype.go = function ( queueid ) {
this.exec ( queueid ); return this;
}
waa.prototype.start = function ( queueid ) {
this.exec ( queueid ); return this;
}
waa.prototype.stop = function ( queueid ) {
var m = wa (':api' );
if ( ! queueid ) return this;
m.queue_torun [ queueid ] = [];
m.queue_isrun [ queueid ] = [];
return this;
}
waa.prototype.kill = function ( queueid ) {
this.stop ( queueid ); return this;
}
waa.prototype.wait = function ( whendone ) {
var m = wa (':api' );
if ( whendone === undefined ) whendone = function () {};
this.queue_torun[m.intqueueid].push ( new Array ( 'stop', whendone ) );
return this;
}
waa.prototype.check = function ( id, queueid ) {
var m = wa (':api' );
// remove id from wait list
for ( var i in m.queue_isrun[queueid] ) {
if ( m.queue_isrun [queueid][i] === id ) {
m.queue_isrun[queueid].splice ( i, 1 );
}
}
if ( m.queue_isrun[queueid].length > 0 ) return m;
m.exec ( queueid, true );
return m;
}
waa.prototype.command = function ( id, command, requesttype ) {
var m = wa (':api' );
m.queue_torun[m.intqueueid].push ( new Array ( 'command', new Array ( id, command, requesttype ) ) );
return this;
}
waa.prototype.edit = function ( id, page, token, content, summary, where ) { // use token = 0 if you don't have one
var m = wa (':api' );
if ( token === 0 ) {
var editreq = m.editreq ++;
m.queue_torun[m.intqueueid].push ( new Array ( 'token', new Array ( 'intok' + editreq, page, 'edit' ) ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'stop' ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'edit', new Array ( id, page, 'intok' + editreq, content, summary, where ) ) );
} else {
m.queue_torun[m.intqueueid].push ( new Array ( 'edit', new Array ( id, page, token, content, summary, where ) ) );
}
return m;
}
waa.prototype.block = function ( id, user, token, expiry, reason, blockoptions ) { // use token = 0 if you don't have one
var m = wa (':api' );
if ( token === 0 ) {
var blockreq = m.blockreq ++;
m.queue_torun[m.intqueueid].push ( new Array ( 'token', new Array ( 'intok' + blockreq, user, 'block' ) ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'stop' ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'block', new Array ( id, user, 'intok' + blockreq, expiry, reason, blockoptions ) ) );
} else {
m.queue_torun[m.intqueueid].push ( new Array ( 'edit', new Array ( id, user, token, expiry, reason, blockoptions ) ) );
}
return m;
}
waa.prototype.rollback = function ( id, user, page, summary ) {
var m = wa (':api' );
m.queue_torun[m.intqueueid].push ( new Array ( 'rtoken', new Array ( id, page ) ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'stop' ) );
m.queue_torun[m.intqueueid].push ( new Array ( 'rollback', new Array ( id, user, page, summary ) ) );
return this;
}
waa.prototype.get = function ( id, page, revisions, properties ) {
var m = wa (':api' );
this.queue_torun[m.intqueueid].push ( new Array ( 'get', new Array ( id, page, revisions ) ) );
return this;
}
waa.prototype.contribs = function ( id, user, count ) {
var m = wa (':api' );
this.queue_torun[m.intqueueid].push ( new Array ( 'contribs', new Array ( id, user, count ) ) );
return this;
}
waa.prototype.token = function ( id, target, token ) {
var m = wa (':api' );
m.queue_torun[m.intqueueid].push ( new Array ( 'token', new Array ( id, target, token ) ) );
return this;
}
// wikiapps misc.
function wam () {
// wikiapps misc
var m = this;
}
wam.prototype.encodewiki = function ( page ) {
return encodeURIComponent ( page );
}
wam.prototype.encodetoarray = function ( xml ) {
var m = wa (':func' );
if ( xml.getElementsByTagName ( 'api' ) [0] ) { var base = xml.getElementsByTagName ( 'api' ) [0]; }
else if ( xml.getElementsByTagName ( 'SearchSuggestion' ) [0] ) { var base = xml.getElementsByTagName ( 'SearchSuggestion' ) [0]; }
else { return false; }
m.array = {};
m.array = m.createrecursive ( base );
//alert('hi');
//alert(m.array);
return m.array;
}
wam.prototype.createrecursive = function ( object ) {
var m = wa (':func' );
var r = {};
var c = {};
for ( var i in object.childNodes ) {
if ( object.childNodes[i].nodeType !== undefined ) {
if ( r [ object.childNodes[i].nodeName ] !== undefined ) {
if ( object.childNodes[i].nodeType === 3 ) continue; // we only ever want one text object, which could have been concatenated
// FIXME: can this duplication be eliminated/shortened?
if ( r [ object.childNodes[i].nodeName ] === null ) {
// if the name already exists, switch it to an array form with index 0.
var tmp = r [ object.childNodes[i].nodeName ];
r [ object.childNodes[i].nodeName ] = [];
r [ object.childNodes[i].nodeName ] [0] = tmp;
var tmp2 = r [ object.childNodes[i].nodeName + '-attr' ];
r [ object.childNodes[i].nodeName + '-attr' ] = [];
r [ object.childNodes[i].nodeName + '-attr' ] [0] = tmp2;
}
else if ( r [ object.childNodes[i].nodeName ] [0] === undefined ) {
var tmp = r [ object.childNodes[i].nodeName ];
r [ object.childNodes[i].nodeName ] = [];
r [ object.childNodes[i].nodeName ] [0] = tmp;
var tmp2 = r [ object.childNodes[i].nodeName + '-attr' ];
r [ object.childNodes[i].nodeName + '-attr' ] = [];
r [ object.childNodes[i].nodeName + '-attr' ] [0] = tmp2;
}
var l = r [ object.childNodes[i].nodeName ].length;
if ( object.childNodes[i].childNodes.length === 0 ) {
r [ object.childNodes[i].nodeName ] [ l ] = object.childNodes[i].nodeValue;
r [ object.childNodes[i].nodeName + '-attr' ] [ l ] = m.returnattributes ( object.childNodes[i] );
} else {
r [ object.childNodes[i].nodeName ] [ l ] = m.createrecursive ( object.childNodes [i] );
r [ object.childNodes[i].nodeName + '-attr' ] [ l ] = m.returnattributes ( object.childNodes[i] );
}
//alert('enddef');
} else {
//alert('def2');
if ( object.childNodes[i].childNodes.length === 0 ) {
if ( object.childNodes[i].nodeType === 3 ) { r [ object.childNodes[i].nodeName ] = concatTextNodes ( object.childNodes[i] ); } else { r [ object.childNodes[i].nodeName ] = object.childNodes[i].nodeValue; }
r [ object.childNodes[i].nodeName + '-attr' ] = m.returnattributes ( object.childNodes[i] );
} else {
r [ object.childNodes[i].nodeName ] = m.createrecursive ( object.childNodes [i] );
r [ object.childNodes[i].nodeName + '-attr' ] = m.returnattributes ( object.childNodes[i] );
}
}
} else {
}
}
return r;
}
wam.prototype.returnattributes = function ( object ) {
var m = wa (':func' );
if ( object.attributes === null ) return null;
if ( object.attributes.length === 0 ) return null;
var r = {};
for ( var i in object.attributes ) {
if ( object.attributes[i].nodeName === undefined ) continue;
r [ object.attributes[i].nodeName ] = object.attributes[i].nodeValue;
}
return r;
}
// wikiapps ajax request.
function waar ( responseId, queueid ) {
// wikiapps ajax request
var waarm = this;
this.requestType = 'GET';
this.responseType = 'xml';
this.requestUrl = '';
this.pageRequest = false;
this.postParams = '';
this.responseId = responseId;
this.queueId = queueid;
this.abort = function () {
if ( waarm.pageRequest != false ) {
waarm.pageRequest.abort ();
return true;
}
}
this.doRequest = function ( runOnComplete, queueid ) {
this.queueid = queueid;
if ( this.requestUrl === '' ) return false;
if ( window.XMLHttpRequest ) { // if good browser
waarm.pageRequest = new XMLHttpRequest ();
}
else if ( window.ActiveXObject ) { // if IE
try { // try request 1
waarm.pageRequest = new ActiveXObject ( "Msxml2.XMLHTTP" );
}
catch ( e ) { // it failed.
try { // try request 2
waarm.pageRequest = new ActiveXObject ( "Microsoft.XMLHTTP" );
}
catch ( e ) { return false; }
}
}
else
{
return false;
}
waarm.pageRequest.onreadystatechange = function () {
if ( waarm.pageRequest.readyState == 4 ) {
if ( waarm.pageRequest.status == 200 ) {
if ( waarm.responseType == 'xml' ) {
wa ( ':api' ).results [ waarm.responseId ] = wa ( ':func' ).encodetoarray ( waarm.pageRequest.responseXML );
} else {
wa ( ':api' ).results [ waarm.responseId ] = waarm.pageRequest.responseText;
}
runOnComplete ( waarm.responseId, waarm.queueid );
}
}
}
if ( this.requestType == 'GET' ) {
// do get request
waarm.pageRequest.open ( 'GET', this.requestUrl, true );
switch ( this.responseType ) {
default: case 'xml':
if ( waarm.pageRequest.overrideMimeType ) { waarm.pageRequest.overrideMimeType ( 'text/xml' ); } else {
waarm.pageRequest.setRequestHeader ( 'Content-type', 'text/xml' ); }
break;
case 'html':
if ( waarm.pageRequest.overrideMimeType ) waarm.pageRequest.overrideMimeType ( 'text/html' );
break;
}
waarm.pageRequest.send ( null );
}
else if ( this.requestType == 'POST' )
{
// do post request
waarm.pageRequest.open ( 'POST', this.requestUrl, true );
waarm.pageRequest.setRequestHeader ( "Content-type", "application/x-www-form-urlencoded" );
waarm.pageRequest.setRequestHeader ( "Content-length", this.postParams.length );
waarm.pageRequest.setRequestHeader ( "Connection", "close" );
waarm.pageRequest.send ( this.postParams );
}
else
{ /* unrecognised */ }
};
return true;
}
// functioning.
concatTextNodes = function ( anySibling ) {
// returns a single string of all text nodes that are (only) siblings to this one in the correct order.
if ( anySibling.nodeType !== 3 ) return false;
var parent = anySibling.parentNode, r = '';
for ( var i = 0, l = parent.childNodes.length; i < l; i ++ ) {
if ( parent.childNodes [i].nodeType !== 3 ) continue;
r += parent.childNodes [i].nodeValue;
}
return r;
}
// prototyping.
// arrays
Array.prototype.count = function () {
return this.length;
}
Array.prototype.contains = function ( searchFor, recursive ) {
if ( recursive === null ) recursive = false;
var haystack = this;
return in_array ( searchFor, haystack, recursive );
}
Array.prototype.getPosition = function ( searchFor ) {
for ( var i = 0, l = this.length; i < l; i ++ ) {
if ( this [i] == searchFor ) return i;
}
return false;
}
// document
/*document.prototype.selected = function () {
if ( window.getSelection ) {
return window.getSelection ();
} else if ( document.getSelection ) {
return document.getSelection ();
} else if ( document.selection ) {
return document.selection.createRange ().text;
} else { return false; }
}*/
// compatibility fixing.
// popups
wa_popups = function ( action ) {
// check popups exist
if ( typeof popupsReady !== 'function' ) return false;
if ( ! popupsReady () ) return false;
switch ( action ) {
default: case 'refresh': case 'remove':
var container = defaultPopupsContainer ();
setupTooltips ( container, true );
case 'add':
setupTooltips ();
break;
}
return true;
}
if ( typeof waLoaded_2 === 'undefined' ) {
var wap = new wa_main ();
var wa = wap.go;
}
// define
var waLoaded_2 = true;
// end
//function test () {
// wa ( ':api' ).command ( 'getcats', 'format=xml&action=query&prop=categories&cllimit=500&titles=' + wa(':func').encodewiki ( 'Ichabod_Washburn' ) ).wait ( function () { /*catMan.cats.getcats ( 0, true );*/ } ).run ();
//wa ( ':api' ).get('t', 'User:Ale_jrb', 5).run();
//}
//hookEvent ('load', test);