User:Timotab/twinklearv.js

// // If TwinkleConfig aint exist. if( typeof( TwinkleConfig ) == 'undefined' ) { TwinkleConfig = {}; } /** TwinkleConfig.summaryAd (string) If ad should be added or not to summary, default TWINKLE */ if( typeof( TwinkleConfig.summaryAd ) == 'undefined' ) { TwinkleConfig.summaryAd = " using TW"; } /** TwinkleConfig.markAIVReportAsMinor (boolean) Defines if a reports to AIV should be marked as minor, if false, default is applied as per preference. */ if( typeof( TwinkleConfig.markAIVReportAsMinor ) == 'undefined' ) { TwinkleConfig.markAIVReportAsMinor = true; } /** TwinkleConfig.confirmUsernameToAIV (boolean) (deprecated) Defines if a username reports to AIV should be confirmed before sent. */ if( typeof( TwinkleConfig.confirmUsernameToAIV ) == 'undefined' ) { TwinkleConfig.confirmUsernameToAIV = true; } /** TwinkleConfig.toolboxButtons (string) If id defined in this array, the button of the action is located inthe toolbox instead of in the actions bar. */ if( typeof( TwinkleConfig.toolboxButtons ) == 'undefined' ) { TwinkleConfig.toolboxButtons = []; } function getChecked( nodelist ) { if( !( nodelist instanceof NodeList ) ) { throw nodelist + " not instance of NodeList"; }	var result = []; for(var i in nodelist ) { if( nodelist[i].checked ) { result.push( nodelist[i].value ); }	}	return result; } function getTexts( nodelist ) { if ( nodelist instanceof HTMLInputElement ) { return [ nodelist.value ]; }	if( !( nodelist instanceof NodeList ) ) { throw nodelist + " not instance of NodeList"; }	var result = []; for(var i in nodelist ) { if( nodelist[i].type == 'text' && nodelist[i].value != '' ) { result.push( nodelist[i].value ); }	}	return result; } function num2order( num ) { switch( num ) { case 1: return ''; case 2: return '2nd'; case 3: return '3rd'; default: return num + 'th'; } } addOnloadHook( twinklearv ); function twinklearv{ var username; if ( wgNamespaceNumber == 3 || wgNamespaceNumber == 2 || ( wgNamespaceNumber == -1 && wgTitle == "Contributions" )){ // If we are on the contributions page, need to parse some then if( wgNamespaceNumber == -1 && wgTitle == "Contributions" ) { username = document.getElementById( 'contentSub' ).getElementsByTagName( 'a' )[0].getAttribute('title').split(':')[1]; } else { username = wgTitle.split( '/' )[0].replace( /\"/, "\\\""); // only first part before any slashes }		if( !username ) { // Something is fishy, there was no user? lets about everything throw "given username was " + username + " and thus makes no sense."; }		var name = isIPAddress( username ) ? 'Report IP' : 'Report'; var title = isIPAddress( username ) ? 'Report IP to Administators' : 'Report user to Administrators'; mw.util.addPortletLink( 'p-cactions', "javascript:twinklearv.callback(\"" + username + "\")", "arv", "tw-arv", name, title ); } } twinklearv.callback = function twinklearvCallback( uid ) { if( uid == wgUserName ){ alert( 'You don\'t want to report yourself, do you?' ); return; }	var Window = new SimpleWindow( 600, 400 ); Window.setTitle( "Advance Reporting and Vetting" ); //Backronym var form = new QuickForm( twinklearv.callback.evaluate ); var categories = form.append( {			type: 'select',			name: 'category',			label: 'Select wanted type of report: ',			event: twinklearv.callback.change_category		} ); categories.append( {			type: 'option',			label: 'Vandalism',			value: 'aiv'		} ); categories.append( {			type: 'option',			label: 'Username',			value: 'username'		} ); categories.append( {			type: 'option',			label: 'Sockpuppet',			value: 'sock'		} ); form.append( {			type: 'field',			label:'Work area',			name: 'work_area'		} ); form.append( {			type: 'hidden',			name: 'uid',			value: uid		} ); var result = form.render; Window.setContent( result ); Window.display; // We must init the var evt = document.createEvent( "Event" ); evt.initEvent( 'change', true, true ); result.category.dispatchEvent( evt ); } twinklearv.callback.change_category = function twinklearvCallbackChangeCategory(e) { var value = e.target.value; var root = e.target.form; var old_area; for( var i in root.childNodes ) { var node = root.childNodes[i]; if( 			node instanceof Element &&			node.getAttribute( 'name' ) == 'work_area' 		) { old_area = node; break; }	}	var work_area = null; switch( value ) { default: case 'aiv': work_area = new QuickForm.element( { 				type: 'field',				label: 'Report user for vandalism',				name: 'work_area'			} ); work_area.append( {				type: 'input',				name: 'page',				label: 'Primary linked page: ',				tooltip: 'Leave blank for no linked page in report',				value: QueryString.exists( 'vanarticle' ) ? QueryString.get( 'vanarticle' ) : ,				event: function(e) {					var value = e.target.value;					var root = e.target.form;					if( value ==  ) {						root.badid.disabled = root.goodid.disabled = true;					} else {						root.badid.disabled = false;						root.goodid.disabled = root.badid.value == '';					}				}			} ); work_area.append( {				type: 'input',				name: 'badid',				label: 'Revision ID for target page when vandalised: ',				tooltip: 'Leave blank for no diff link',				value: QueryString.exists( 'vanarticlerevid' ) ? QueryString.get( 'vanarticlerevid' ) : ,				disabled: !QueryString.exists( 'vanarticle' ),				event: function(e) {					var value = e.target.value;					var root = e.target.form;					root.goodid.disabled = value == ;				}			} ); work_area.append( {				type: 'input',				name: 'goodid',				label: 'Last good revision ID before vandalism of target page: ',				tooltip: 'Leave blank for diff link to previous revision',				value: QueryString.exists( 'vanarticlegoodrevid' ) ? QueryString.get( 'vanarticlegoodrevid' ) : '',				disabled: !QueryString.exists( 'vanarticle' ) || QueryString.exists( 'vanarticlerevid' )			} ); work_area.append( {				type: 'checkbox',				name: 'arvtype',				list: [					{ 						label: 'Vandalism after final warning given',						value: 'final'					},					{ 						label: 'Vandalism after recent release of block',						value: 'postblock'					},					{ 						label: 'Evidently vandalism only account',						value: 'vandalonly'					},					{ 						label: 'Account is evidently a spambot or a compromized account',						value: 'spambot'					}				]			} ); work_area.append( {				type: 'textarea',				name: 'reason',				label: 'Comment: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'username': work_area = new QuickForm.element( { 				type: 'field',				label: 'Report username violation',				name: 'work_area'			} ); var types = work_area.append( {				type: 'field',				label: 'Type of violation',				tooltip: 'A valid report must include at least one of following types'			} ); types.append ( { 				type:'header', 				label:'Confusing usernames',				tooltip: 'Confusing usernames that make it unduly difficult to identify users by their username'			} ); types.append( {				type: 'checkbox',				name: 'arvtype',				list: [					{ 						label: 'Usernames that closely resemble the name of another Wikipedia user and may cause confusion',						value: 'closely resembles the name of another wikipedia user and may cause confusion'					},					{						label: 'Usernames that confusingly refer to a Wikipedia process, namespace, or toolbar item',						value: 'confusingly refers to a Wikipedia process, namespace or toolbar item'					},					{						label: 'Usernames that consist of a lengthy or apparently random sequence of characters',						value: 'consists of a lengthy or apparently random sequence of characters',						tooltip: 'E.g. "aaaaaaaaaaaa" or "ghfjkghdfjgkdhfjkg"'					},					{						label: 'Usernames that are extremely lengthy',						value: 'is extremely lengthy',						tooltip: 'E.g. "Super Ultra Mege Bob of Waverly Drive from Mars146366"' 					} ]			} );		types.append ( { type:'header', label:'Misleading usernames', tooltip: 'Misleading usernames that imply relevant, misleading things about the user' } );		types.append( { type: 'checkbox', name: 'arvtype', list: [ {						label: 'Usernames that imply the user is an admin or other official figure on Wikipedia, or of the Wikimedia foundation', value: 'implies that the user is an admin or other official figure on Wikipedia, or of the Wikimedia foundation' },					{						label: 'Usernames that match the name of a well-known living or recently deceased person', value: 'matches the name of a well-known living or recently deceased person', tooltip: 'Unless user verifiably is that person. Wikipedians with articles is a list of such users.' },					{						label: 'Usernames that imply an automated account', value: 'implies an automated account', tooltip: 'Such as names containing "robot", "bot", or a variation thereof. Such usernames are reserved for bot accounts' }				]			} );		types.append ( { type:'header', label:'Disruptive usernames', tooltip: 'Disruptive usernames that disrupt or misuse Wikipedia, or imply an intent to do so' } );		types.append( { type: 'checkbox', name: 'arvtype', list: [ {						label: 'Usernames that are similar to those used by known vandals', value: 'is similar to those used by known vandals' },					{						label: 'Usernames that are attacks on specific users', value: 'is an attack on an specific user' },					{						label: 'Usernames that contain personal information about people', value: 'contains personal information about people', tooltip: 'Such as a telephone number or street address' },					{						label: 'Usernames that allude to hacking, trolling, vandalism, legal threats, or computer viruses', value: 'alludes to hacking, trolling, vandalism, legal threats, or computer viruses' },					{						label: 'Usernames that include profanity, or obscenities, or references to genitalia or sexual slang', value: 'includes profanities, obscenities, or references to genitalias or sexual slangs' }				]			} );		types.append ( { type:'header', label:'Promotional usernames', tooltip: 'Promotional usernames that attempt to promote a group or company on Wikipedia' } );		types.append( { type: 'checkbox', name: 'arvtype', list: [ {						label: 'Usernames that match the name of a company or group', value: 'matches the name of a company or group', tooltip: 'Especially if the user promotes it' },					{						label: 'E-mail addresses or web page addresses are generally considered likely to be promotional', value: 'resembles e-mail addresses or web page addresses and is likely to be promotional', tooltip: 'Note that for a long time, email addresses were not prohibited. Usernames created before January 1, 2007 that are email addresses are grandfathered under this policy and are not prohibited' }				]			} );		types.append ( { type:'header', label:'Offensive usernames', tooltip: 'Offensive usernames that may make harmonious editing difficult or impossible' } );		types.append( { type: 'checkbox', name: 'arvtype', list: [ {						label: 'Usernames that promote a controversial or potentially inflammatory point of view', value: 'promotes a controversial or potentially inflammatory point of view' },					{						label: 'Usernames that are defamatory or insulting to other people or groups', value: 'is defamatory or insulting to other people or groups' },					{						label: 'Usernames that invoke the name of a religious figure or religion in a distasteful, disrespectful, or provocative way, or promote one religion over another', value: 'invokes the name of a religious figure/religion in a distasteful, disrespectful, or provocative way, or promotes one religion over another', tooltip: 'Note that simple expressions of faith are allowed unless they are disruptive, but are discouraged' },					{						label: 'Usernames that refer to real-world violent actions', value: 'refers to a violent real-world action' },					{						label: 'Usernames that refer or include allusions to racism, sexism, hate speech, et cetera', value: 'refers or includes allusions to racism, sexism, hate speech, et cetera' },					{						label: 'Usernames that refer to a medical condition or disability, especially in a belittling way', value: 'refers to a medical condition or disability' },					{						label: 'Usernames that include slurs, or references to reproductive or excretory bodily functions', value: 'includes slurs or references to reproductive/excretory bodily functions' }				]			} );		work_area.append( { type: 'textarea', name: 'reason', label: 'Comment:' } );		work_area.append( { type:'submit' } );		work_area = work_area.render;		old_area.parentNode.replaceChild( work_area, old_area );		break;	case 'sock':		work_area = new QuickForm.element( { type: 'field', label: 'Report suspected sockpuppeter', name: 'work_area' } );		var sock_area = work_area.append( { type:'div' } );		sock_area.append( { type: 'button', label: 'More socks', name: 'more_socks_button', event: function (e){ var area = e.target.parentNode.parentNode; var new_node = new QuickForm.element( {							type: 'input',							label: 'Sockpuppet: ',							name: 'sockpuppet'						} ); if( area.childNodes.length > 1 ) { new_node.append( {								type: 'button',								label: 'remove',								event: function (e){									var node_to_remove = e.target.parentNode.parentNode;									node_to_remove.parentNode.removeChild( node_to_remove );								}							} ); }					area.insertBefore( new_node.render, area.lastChild ); }			} );		work_area.append( { type: 'textarea', label: 'Evidence:', name: 'evidence' } );		work_area.append( { type:'submit' } );		work_area = work_area.render;		old_area.parentNode.replaceChild( work_area, old_area );		var evt = document.createEvent( "MouseEvent" );		evt.initEvent( 'click', true, true );		work_area.form.more_socks_button.dispatchEvent( evt );		break;	} } twinklearv.callback.evaluate = function(e) {	var form = e.target;	var reason = "";	if( form.reason ) {		comment = form.reason.value;	}	var uid = form.uid.value;	switch( form.category.value ) {	default:	case 'aiv':		var types = getChecked( form.arvtype );		if( types.length == 0 && comment == '' ) {			alert( 'You must specify some reason' );			return;		}		types = types.map( function(v) { switch(v) { case 'final': return 'vandalism after final warning'; break; case 'postblock': return 'vandalism directly after release of block'; break; case 'spambot': return 'account is evidently a spambot or a compromized account'; break; case 'vandalonly': return 'actions evidently indicate a vandalism only account'; break; }			} ).join( ', ' );		if( form.page.value !=  ) {			reason += 'On Category):/i, ':$1:' ) + ;			if( form.badid.value !=  ) {				var query = {					'title': form.page.value,					'diff': form.badid.value,					'oldid': form.goodid.value				};				reason += ' ([' + mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ) + ' diff])';			}			reason += ';';		}		if( types ) {			reason += " " + types;		}		if (comment !=  ) {			reason += ". " + comment + '.';		}		Status.init( form );		Status.status( "Grabbing AIV page" );		var xmlhttp = sajax_init_object;		xmlhttp.query = {			'title': 'Wikipedia:Administrator intervention against vandalism',			'action': 'submit',			'section': 1		};		xmlhttp.params = { reason:reason, uid:uid };		xmlhttp.overrideMimeType('text/xml');		xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { uid = this.params.uid; reason = this.params.reason; var form = this.responseXML.getElementById('editform'); if( !form ) { Status.error( 'Failed to retrieve edit form.' ); return; }			var text = form.wpTextbox1.value; var re = new RegExp( "\\{\\{\\s*(?:(?:[Ii][Pp])?[Vv]andal|[Uu]serlinks)\\s*\\|\\s*(?:1=)?\\s*" + RegExp.escape( uid, true ) + "\\s*\\}\\}" ); var myArr; if( ( myArr = re.exec( text ) ) ) { Status.info( 'Report already present, will not add a new one' ); return; }			Status.status( 'Adding new report...' ); var postData = { 'wpMinoredit': TwinkleConfig.markAIVReportAsMinor ? '' : form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Reporting ' + uid + '.'+ TwinkleConfig.summaryAd, 'wpTextbox1': text + '* - ' + reason + ' ' + '' };			var xmlhttp = sajax_init_object; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { window.location = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace( '$1', 'Wikipedia:Administrator intervention against vandalism' ); } xmlhttp.send( QueryString.create( postData ) ); }		xmlhttp.send( null ); break; case 'username': var types = getChecked( form.arvtype ); if( types.length == 0 ) { alert( 'You must specify at least one breached violation' ); return; }		types = types.map( function( v ) { return v.toLowerCaseFirstChar; } ); if( types.length <= 2 ) { types = types.join( ' and ' ).toUpperCaseFirstChar; } else { types = [ types.slice( 0, -1 ).join( ', ' ), types.slice( -1 ) ].join( ', and ' ).toUpperCaseFirstChar; }		reason = "*\{\{userlinks|" + uid + "\}\} &mdash; Violation of username policy because: " + types + "; "; if (comment != '' ) { reason += "" + comment.toUpperCaseFirstChar + ". "; }		reason += "\~\~\~\~"; Status.init( form ); Status.status( "Grabbing UAA page" ); var xmlhttp = sajax_init_object; xmlhttp.query = { 'title': 'Wikipedia:Usernames for administrator attention', 'action': 'submit', 'section': 1 };		xmlhttp.params = { reason:reason, uid:uid }; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { uid = this.params.uid; reason = this.params.reason; var form = this.responseXML.getElementById('editform'); if( !form ) { Status.error( 'Failed to retrieve edit form.' ); return; }			var text = form.wpTextbox1.value; Status.status( 'Adding new report...' ); var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Reporting ' + uid + '.'+ TwinkleConfig.summaryAd, 'wpTextbox1': text.replace( /-->/, "-->\n" + reason.replace( '\$', "$$$$" ) ) };			var xmlhttp = sajax_init_object; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { window.location = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace( '$1', 'Wikipedia:Usernames for administrator attention' ); } xmlhttp.send( QueryString.create( postData ) ); }		xmlhttp.send( null ); break; case 'sock': var sockpuppets = getTexts( form.sockpuppet ); var evidence = form.evidence.value; Status.init( form ); Status.status( 'Grabbing data of eventual previous reports' ); var xmlhttp = sajax_init_object; xmlhttp.query = { 'title': 'Special:Prefixindex', 'from': 'Suspected sock puppets/' + uid, 'namespace': 4 };		xmlhttp.params = { uid:uid, sockpuppets:sockpuppets, evidence:evidence }; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { var a_tags = this.responseXML.getElementsByTagName('a'); var re = new RegExp( RegExp.escape( 'Suspected sock puppets/' + this.params.uid ) ); var number = 0; for( var i in a_tags ) { var title = a_tags[i].title; if( re.exec( title ) ) { var n = /\(\s*(\d+)(?:th|nd|rd|st)\s*\)\s*$/.exec( title ); if( n && n[1] > number ) { number = n[1]; } else if( number == 0 ) { number = 1; }				}			}			if( number == 0 ) { this.params.numbering = this.params.number = ''; } else { this.params.number = num2order( parseInt( number ) + 1); this.params.numbering = ' (' + this.params.number + ')'; }			Status.status( 'Creating report page Suspected sock puppets/' + this.params.uid + this.params.numbering + ''); var xmlhttp = sajax_init_object; xmlhttp.query = { 'title': 'Wikipedia:Suspected sock puppets/' + this.params.uid + this.params.numbering, 'action': 'submit' };			xmlhttp.params = this.params; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { var form = this.responseXML.getElementById('editform'); var text = "===User:" + this.params.uid + "===\n" + ";Suspected sockpuppeteer\n" + ":\{\{user5|" + this.params.uid + "\}\}\n\n" + ";Suspected sockpuppets\n" + this.params.sockpuppets.map( function(v) { return ":\{\{user5|" + v + "\}\}" } ).join( "\n" ) + "\n\n" + ";Report submission by\n" + "\~\~\~\~\n\n" + ";Evidence\n" + this.params.evidence + "\n\n" + ";Comments\n\n\n" + ";Conclusions\n\n\n" + "\n \n"; var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Creating report for User:" + this.params.uid + '.' + TwinkleConfig.summaryAd, 'wpTextbox1': text };				var xmlhttp = sajax_init_object; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { Status.info( 'Report created' ) } xmlhttp.send( QueryString.create( postData ) ); }			xmlhttp.send( null ); Status.status( 'Linking report to open cases'); var xmlhttp = sajax_init_object; xmlhttp.query = { 'title': 'Wikipedia:Suspected sock puppets', 'section': 4, 'action': 'submit' };			xmlhttp.params = this.params; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { var form = this.responseXML.getElementById('editform'); text = form.wpTextbox1.value.replace( //, "$1\n\{\{Wikipedia:Suspected sock puppets/" + this.params.uid + this.params.numbering + "\}\}"); var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Adding report for User:" + this.params.uid + '.' + TwinkleConfig.summaryAd, 'wpTextbox1': text };				var xmlhttp = sajax_init_object; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true ); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { Status.info( 'Added to open cases' ) } xmlhttp.send( QueryString.create( postData ) ); }			xmlhttp.send( null ); Status.status( 'Notifying suspected sockpuppeter'); var xmlhttp = sajax_init_object; xmlhttp.query = { 'title': 'User talk:' + this.params.uid, 'action': 'submit' };			xmlhttp.params = this.params; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true); xmlhttp.onload = function { var form = this.responseXML.getElementById('editform'); text = form.wpTextbox1.value; var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Notifying about suspicion of sockpuppertering." + TwinkleConfig.summaryAd, 'wpTextbox1': text + "\n\{\{subst:socksuspectnotice|1=" + this.params.uid + this.params.numbering + "\}\} \~\~\~\~" };				var xmlhttp = sajax_init_object; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { Status.info( 'Suspected sockpuppeter notified' ) } xmlhttp.send( QueryString.create( postData ) ); }			xmlhttp.send( null ); var statusIndicator = document.createElement( 'div' ); Status.status( [ statusIndicator ] ); statusIndicator.appendChild( document.createTextNode( 'Tagging suspected socs, status: ' ) ); statusIndicator.appendChild( document.createTextNode( '0%' ) ); var nofnodes = this.params.sockpuppets.length * 2; counter = 0; updateCounter = function(obj, total) { obj.replaceChild( document.createTextNode( parseInt( 100 * ++counter/total ) + '%' ), obj.lastChild ); if( counter == total ) { Status.info( 'tagging of sockpuppets complete.' ); }			}			for( var i in this.params.sockpuppets ) { (function(current, total, obj, params) {						var xmlhttp = sajax_init_object;						xmlhttp.query = {							'title': 'User:' + params.sockpuppets[current],							'action': 'submit'						};						xmlhttp.overrideMimeType('text/xml');						xmlhttp.open( 'GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( xmlhttp.query ), true);						xmlhttp.onload = function {							updateCounter( obj, total );							var form = this.responseXML.getElementById('editform');							text = form.wpTextbox1.value;							if( /\{\{sockpuppet.*?\}\}/.exec( text ) ) { // already marked as a sock, just ignore then								updateCounter( obj, total );								return;							}							var postData = {								'wpMinoredit': form.wpMinoredit.checked ?  : undefined,								'wpWatchthis': form.wpWatchthis.checked ?  : undefined,								'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Adding supsected sockpuppet tag for suspected sockpuppeter User:" + params.uid + '.' + TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{subst:socksuspect|1=" + params.uid + "\}\}\n" + text };							var xmlhttp = sajax_init_object; xmlhttp.current = this.current; xmlhttp.overrideMimeType('text/xml'); xmlhttp.open( 'POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( this.query ), true); xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); xmlhttp.onload = function { updateCounter( obj, total ); }							xmlhttp.send( QueryString.create( postData ) ); }						xmlhttp.send( null ); })( i, nofnodes, statusIndicator, this.params );			}		}		xmlhttp.send( null );	} } //