/* ============================================== *\
** 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);