window.setTimeout( function( self ) { self.post( self.postData ); }, retry * 1000, self );
return;
} else {
self.statelem.error( "Error " + status + " occurred while posting the document." );
}
}
return;
}
var xmlDoc;
xmlDoc = self.responseXML = this.responseXML;
var xpathExpr = 'boolean(//div[@class=\'previewnote\']/p/strong[contains(.,\'Sorry! We could not process your edit due to a loss of session data\')])';
var nosession = xmlDoc.evaluate( xpathExpr, xmlDoc, null, XPathResult.BOOLEAN_TYPE, null ).booleanValue;
if( nosession ) {
// Grabbing the shipping token, and repost
var new_token = xmlDoc.evaluate( '//input[@name="wfEditToken"]/@value', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue;
self.postData['wfEditToken'] = new_token;
self.post( self.postData );
} else {
if( self.onsuccess ) {
self.onsuccess( self );
} else {
var link = document.createElement( 'a' );
link.setAttribute( 'href', mw.config.get('wgArticlePath').replace( '$1', self.query['title'] ) );
link.setAttribute( 'title', self.query['title'] );
link.appendChild( document.createTextNode( self.query['title'] ) );  
self.statelem.info( [ 'completed (' , link , ')' ] );
}
Wikipedia.actionCompleted;
}
};
xmlhttp.send( QueryString.create( this.postData ) );
},
get: function {
this.onloading( this );
var redirect_query = {
'action': 'query',
'titles': this.query['title'],
'redirects': ''
}  
var wikipedia_api = new Wikipedia.api( "resolving eventual redirect", redirect_query, this.postget, this.statelem );
wikipedia_api.parent = this;
wikipedia_api.post;
},
postget: function {
var xmlDoc = self.responseXML = this.responseXML;
var to = xmlDoc.evaluate( '//redirects/r/@to', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue;
if( !this.followRedirect ) {
this.parent.statelem.info('ignoring eventual redirect');
} else if( to ) {
this.parent.query['title'] = to;
}
this.parent.onloading( this );
var xmlhttp = sajax_init_object;
Wikipedia.dump.push( xmlhttp );
xmlhttp.obj = this.parent;
xmlhttp.overrideMimeType('text/xml');
xmlhttp.open( 'GET' , mw.config.get('wgServer') + wgScriptPath + '/index.php?' + QueryString.create( this.parent.query ), true);
xmlhttp.onerror = function {
var self = this.obj;
self.statelem.error( "Error " + this.status + " occurred while receiving the document." );
}
xmlhttp.onload = function {
this.obj.onloaded( this.obj );
this.obj.responseXML = this.responseXML;
this.obj.responseText = this.responseText;
this.obj.oninit( this.obj );
};
xmlhttp.send( null );
},
onloading: function {
this.statelem.status( 'loading data...' );
},
onloaded: function {
this.statelem.status( 'data loaded...' );
}
}  
Number.prototype.zeroFill = function( length ) {
var str = this.toFixed;
if( !length ) { return str; }
while( str.length < length ) { str = '0' + str; }
return str;
}  
Mediawiki = {};  
Mediawiki.Template = {
parse: function( text, start ) {
var count = -1;
var level = -1;
var equals = -1;
var current = '';
var result = {
name: '',
parameters: {}
};  
for( var i = start; i < text.length; ++i ) {
var test3 = text.substr( i, 3 );
if( test3 == '\{\{\{' ) {
current += '\{\{\{';
i += 2;
++level;
continue;
}
if( test3 == '\}\}\}' ) {
current += '\}\}\}';
i += 2;
--level;
continue;
}
var test2 = text.substr( i, 2 );
if( test2 == '\{\{' ) {
current += '\{\{';
++i;
++level;
continue;
}
if( test2 == '\}\}' ) {
current += '\}\}';
++i;
--level;  
if( level <= 0 ) {
if( count == -1 ) {
result.name = current.substring(2).trim;
++count;
} else {
if( equals != -1 ) {
var key = current.substring( 0, equals ).trim;
var value = current.substring( equals ).trim;
result.parameters[key] = value;
equals = -1;
} else {
result.parameters[count] = current;
++count;
}
}
break;
}
continue;
}  
if( text.charAt(i) == '|' && level <= 0 ) {
if( count == -1 ) {
result.name = current.substring(2).trim;
++count;
} else {
if( equals != -1 ) {
var key = current.substring( 0, equals ).trim;
var value = current.substring( equals + 1 ).trim;
result.parameters[key] = value;
equals = -1;
} else {
result.parameters[count] = current;
++count;
}
}
current = '';
} else if( equals == -1 && text.charAt(i) == '=' && level <= 0 ) {
equals = current.length;
current += text.charAt(i);
} else {
current += text.charAt(i);
}
}  
return result;
}
}  
Mediawiki.Page = function mediawikiPage( text ) {
this.text = text;
}  
Mediawiki.Page.prototype = {
text: '',
removeLink: function( link_target ) {
var first_char = link_target.substr( 0, 1 );
var link_re_string = "[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( link_target.substr( 1 ), true );
var link_simple_re = new RegExp( "\\[\\[(" + link_re_string + ")\\|?\\]\\]", 'g' );
var link_named_re = new RegExp( "\\[\\[" + link_re_string + "\\|(.+?)\\]\\]", 'g' );
if( link_simple_re.test(this.text) ) {
this.text = this.text.replace( link_simple_re, "$1" );
} else {
this.text = this.text.replace( link_named_re, "$1" );
}
},
commentOutImage: function( image, reason ) {
var unbinder = new Unbinder( this.text );
unbinder.unbind( '' );  
reason = reason ? ' ' + reason + ': ' : '';
var first_char = image.substr( 0, 1 );
var image_re_string = "[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( image.substr( 1 ), true );  
/*
- Check for normal image links, i.e.
- Will eat the whole link
- /
var links_re = new RegExp( "\\[\\[[Ii]mage:\\s*" + image_re_string );
var allLinks = unbinder.content.splitWeightedByKeys( *, * ).uniq;
for( var i = 0; i < allLinks.length; ++i ) {
if( links_re.test( allLinks[i] ) ) {
var replacement = '';
unbinder.content = unbinder.content.replace( allLinks[i], replacement, 'g' );
}
}
// unbind the newly created comments
unbinder.unbind( '' );  
/*
- Check for gallery images, i.e. instances that must start on a new line, eventually preceded with some space, and must include Image: prefix
- Will eat the whole line.
- /
var gallery_image_re = new RegExp( "(^\\s*[Ii]mage:\\s*" + image_re_string + ".*?$)", 'mg' );
unbinder.content.replace( gallery_image_re, "" );  
// unbind the newly created comments
unbinder.unbind( '' );
/*
- Check free image usages, for example as template arguments, might have the Image: prefix excluded, but must be preceeded by an |
- Will only eat the image name and the preceeding bar and an eventual named parameter
- /
var free_image_re = new RegExp( "(\\|\\s*(?:[\\w\\s]+\\=)?\\s*(?:[Ii]mage:\\s*)?" + image_re_string + ")", 'mg' );
unbinder.content.replace( free_image_re, "" );  
// Rebind the content now, we are done!
this.text = unbinder.rebind;
},
addToImageComment: function( image, data ) {
var first_char = image.substr( 0, 1 );
var image_re_string = "[Ii]mage:\\s*[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( image.substr( 1 ), true );
var links_re = new RegExp( "\\[\\[" + image_re_string );
var allLinks = this.text.splitWeightedByKeys( *, * ).uniq;
for( var i = 0; i < allLinks.length; ++i ) {
if( links_re.test( allLinks[i] ) ) {
var replacement = allLinks[i];
// just put it at the end?
replacement = replacement.replace( /\]\]$/, '|' + data + ']]' );
this.text = this.text.replace( allLinks[i], replacement, 'g' );
}
}
var gallery_re = new RegExp( "^(\\s*" + image_re_string + '.*?)\\|?(.*?)$', 'mg' );
var replacement = "$1|$2 " + data;
this.text = this.text.replace( gallery_re, replacement );
},
removeTemplate: function( template ) {
var first_char = template.substr( 0, 1 );
var template_re_string = "(?:[Tt]emplate:)?\\s*[" + first_char.toUpperCase + first_char.toLowerCase + ']' + RegExp.escape( template.substr( 1 ), true );
var links_re = new RegExp( "\\\{\\\{" + template_re_string );
var allTemplates = this.text.splitWeightedByKeys( '', [ '}' ] ).uniq;
for( var i = 0; i < allTemplates.length; ++i ) {
if( links_re.test( allTemplates[i] ) ) {
this.text = this.text.replace( allTemplates[i], '', 'g' );
}
}  
},
getText: function {
return this.text;
}
}  
// Simple helper functions to see what groups a user might belong