text:
User:Flewis/twinklexfd.js

// If TwinkleConfig aint exist. if( typeof( TwinkleConfig ) == 'undefined' ) { TwinkleConfig = function {}; }

/** TwinkleConfig.summaryAd (string) If ad should be added or not to summary, default TWINKLE */ if( typeof( TwinkleConfig.summaryAd ) == 'undefined' ) { TwinkleConfig.summaryAd = " using TW"; }

function num2order( num ) { switch( num ) { case 1: return ''; case 2: return '2nd'; case 3: return '3rd'; default: return num + 'th'; } } function twinklexfd { if( wgNamespaceNumber < 0 || wgCurRevisionId == false ) { return; }	if (twinkleConfigExists) {		mw.util.addPortletLink( 'p-cactions', "javascript:twinklexfd.callback", "xfd", "tw-xfd", "Anything for deletion", ""); }	else {		mw.util.addPortletLink('p-cactions', 'javascript:alert("Your account is too new to use Twinkle.");', 'xfd', 'tw-xfd', 'Anything for deletion', ''); } } $(twinklexfd);

twinklexfd.callback = function twinklexfdCallback {

var Window = new SimpleWindow( 600, 300 ); Window.setTitle( "Anything for deletion" ); var form = new QuickForm( twinklexfd.callback.evaluate ); var categories = form.append( {			type: 'select',			name: 'category',			label: 'Select wanted type of category: ',			tooltip: 'When activated, a default choice is choosen, based on what namespace you are in. This default should be the most appropriate',			event: twinklexfd.callback.change_category		} ); categories.append( {			type: 'option',			label: 'Afd',			selected: wgNamespaceNumber == Namespace.MAIN,			value: 'afd'		} ); categories.append( {			type: 'option',			label: 'Tfd',			selected: wgNamespaceNumber == Namespace.TEMPLATE,			value: 'tfd'		} ); categories.append( {			type: 'option',			label: 'Ifd/PUI',			selected: wgNamespaceNumber == Namespace.IMAGE,			value: 'ifd'		} ); categories.append( {			type: 'option',			label: 'Cfd',			selected: wgNamespaceNumber == Namespace.CATEGORY,			value: 'cfd'		} ); categories.append( {			type: 'option',			label: 'Mfd',			selected: [ Namespace.IMAGE, Namespace.MAIN, Namespace.TEMPLATE, Namespace.CATEGORY ].indexOf( wgNamespaceNumber ) == -1 ,			value: 'mfd'		} ); categories.append( {			type: 'option',			label: 'Rfd',			selected: QueryString.equals('redirect', 'no'),			value: 'rfd'		} ); categories.append( {			type: 'option',			label: 'Sfd',			disabled: true,			value: 'sfd'		} );

form.append( {			type: 'field',			label:'Work area',			name: 'work_area'		} );

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 );

}

twinklexfd.callback.change_category = function twinklexfdCallbackChangeCategory(e) { var value = e.target.value; var root = e.target.form; var old_area; var childNodes = root.childNodes; for( var i = 0; i < childNodes.length; ++i ) { var node = childNodes[i]; if( 			node instanceof Element &&			node.getAttribute( 'name' ) == 'work_area' 		) { old_area = node; break; }	}	var work_area = null;

switch( value ) { case 'afd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Articles for deletion',				name: 'work_area'			} ); var afd_category = work_area.append( { 				type:'select',				name:'xfdcat',				label:'Choose what category this nomination belongs in' 			} );

afd_category.append( { type:'option', label:'Unknown', value:'?', selected:true } ); afd_category.append( { type:'option', label:'Media and music', value:'M' } ); afd_category.append( { type:'option', label:'Organisation, corporation, or product', value:'O' } ); afd_category.append( { type:'option', label:'Biographical', value:'B' } ); afd_category.append( { type:'option', label:'Society topics', value:'S' } ); afd_category.append( { type:'option', label:'Web or internet', value:'W' } ); afd_category.append( { type:'option', label:'Games or sports', value:'G' } ); afd_category.append( { type:'option', label:'Science and technology', value:'T' } ); afd_category.append( { type:'option', label:'Fiction and the arts', value:'F' } ); afd_category.append( { type:'option', label:'Places and transportation', value:'P' } ); afd_category.append( { type:'option', label:'Indiscernible or unclassifiable topic', value:'I' } ); afd_category.append( { type:'option', label:'Debate not yet sorted', value:'U' } );

work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'tfd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Templates for deletion',				name: 'work_area'			} ); work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'mfd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Miscellany for deletion',				name: 'work_area'			} ); work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'ifd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Images for deletion',				name: 'work_area'			} ); work_area.append( {				type: 'checkbox',				name: 'pui',				list: [					{						label: 'Possible unfree image',						value: 'pui',						tooltip: 'Image have disputed source or licensing information'					}				]			} ); work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'cfd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Categories for discussion',				name: 'work_area'			} ); var cfd_category = work_area.append( {				type: 'select',				label: 'Choose type of action wanted: ',				name: 'xfdcat',				event: function(e) {					var value = e.target.value;					var target = e.target.form.xfdtarget;					if( value == 'cfd' ) {						target.disabled = true;					} else {						target.disabled = false;					}				}			} ); cfd_category.append( { type:'option', label: 'Deletion', value: 'cfd', selected:true } ); cfd_category.append( { type:'option', label:'Merge', value:'cfm' } ); cfd_category.append( { type:'option', label:'Renaming', value:'cfr' } ); cfd_category.append( { type:'option', label:'Convert into article', value:'cfc' } );

work_area.append( {				type: 'input',				name: 'xfdtarget',				label: 'Target page: ',				disabled: true,				value: ''			} ); work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; case 'rfd': work_area = new QuickForm.element( { 				type: 'field',				label: 'Redirects for discussion',				name: 'work_area'			} ); work_area.append( {				type: 'textarea',				name: 'xfdreason',				label: 'Reason: '			} ); work_area.append( { type:'submit' } ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; default: work_area = new QuickForm.element( { 				type: 'field',				label: 'Nothing for anything',				name: 'work_area'			} ); work_area = work_area.render; old_area.parentNode.replaceChild( work_area, old_area ); break; } }

twinklexfd.callbacks = { afd: { main: function ( self ) { var xmlDoc = self.responseXML; var titles = xmlDoc.evaluate( '//allpages/p/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

// There has been no earlier entries with this prefix, just go on. if( titles.snapshotLength <= 0 ) { self.params.numbering = self.params.number = ''; numbering = number = ''; } else { var number = 0; for( var i = 0; i < titles.snapshotLength; ++i ) { var title = titles.snapshotItem(i).value;

// First, simple test, is there an instance with this exact name? if( title == 'Wikipedia:Articles for deletion/' + wgPageName ) { number = Math.max( number, 1 ); continue; }

var order_re = new RegExp( '^' +							RegExp.escape( 'Wikipedia:Articles for deletion/' + wgPageName, true ) +							'\\s*\\(\\s*(\\d+)(?:(?:th|nd|rd|st) nom(?:ination)?)?\\s*\\)\\s*$'					); var match = order_re.exec( title );

// No match; A non-good value if( match == null ) { continue; }

// A match, set number to the max of current number = Math.max( number, Number(match[1]) ); }				self.params.number = num2order( parseInt( number ) + 1); self.params.numbering = number > 0 ? ' (' + self.params.number + ' nomination)' : ''; }

Status.info( 'Next discussion page","Articles for deletion/' + wgPageName + self.params.numbering + '' );

// Tagging article var query = { 'title': wgPageName, 'action': 'submit' };			var wikipedia_wiki = new Wikipedia.wiki( 'Tagging article with deletion tag', query, twinklexfd.callbacks.afd.article ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Discussion page query = { 'title': 'Wikipedia:Articles for deletion/' + wgPageName + self.params.numbering, 'action': 'submit' };

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the discussion page";

var wikipedia_wiki = new Wikipedia.wiki( 'Creating article deletion discussion page', query, twinklexfd.callbacks.afd.discussionPage ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Todays list var date = new Date;

query = { 'title': 'Wikipedia:Articles for deletion/Log/' + date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate, 'action': 'submit' };

var wikipedia_wiki = new Wikipedia.wiki( 'Adding discussion to todays list', query, twinklexfd.callbacks.afd.todaysList ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Notification to first contributor

var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }			var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };				var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.afd.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }			var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = self.params; wikipedia_api.post; },		article: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per memo 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Nominated for deletion; see Articles for deletion/" + wgPageName + self.params.numbering + '.'+ TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{" + ( self.params.number == '' ? "subst:afd\}\}\n" : 'subst:afdx|' + self.params.number + "}}\n" ) + form.wpTextbox1.value };			self.post( postData ); },		discussionPage: function( self ) { var form = self.responseXML.getElementById('editform'); 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 deletion discussion page for \[\[" + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{subst:afd2|pg=" + wgPageName + "|cat=" + self.params.xfdcat + "|text=" + self.params.reason + " \~\~\~\~\}\}\n" };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); var old_text = form.wpTextbox1.value;

var text = old_text.replace( /(<\!-- Add new entries to the TOP of the following list -->\n+)/, "$1\{\{subst:afd3|pg=" + wgPageName + self.params.numbering + "\}\}\n"); if( text == old_text ) { self.statelem.error( 'failed to find target spot to add the discussion to.' ); 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 \[\[Wikipedia:Articles for deletion/" + wgPageName + self.params.numbering + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:AFDWarning|1=" + wgPageName + ( self.params.numbering !=  ? '|order= ' + self.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': 'AfD nomination of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	},	tfd: { taggingTemplate: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per memo 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Nominated for deletion; see \[\[Wikipedia:Templates for deletion#" + wgPageName + '\]\].'+ TwinkleConfig.summaryAd, 'wpTextbox1': " \{\{tfd|" + wgTitle + "\}\}\n " + form.wpTextbox1.value };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); var old_text = form.wpTextbox1.value; text = old_text.replace( '-->', "-->\n\{\{subst:tfd2|" + wgTitle + "|text=" + self.params.reason + " \~\~\~\~\}\}"); if( text == old_text ) { self.statelem.error( 'failed to find target spot to add the discussion to.' ); 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 Template:" + wgTitle + '.' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:tfdnotice|1=" + wgTitle + "\}\} \~\~\~\~"; 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': 'TfD nomination of \[\[Template:' + wgTitle + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	},	mfd: { main: function( self ) { var xmlDoc = self.responseXML; var titles = xmlDoc.evaluate( '//allpages/p/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

// There has been no earlier entries with this prefix, just go on. if( titles.snapshotLength <= 0 ) { self.params.numbering = self.params.number = ''; numbering = number = ''; } else { var number = 0; for( var i = 0; i < titles.snapshotLength; ++i ) { var title = titles.snapshotItem(i).value;

// First, simple test, is there an instance with this exact name? if( title == 'Wikipedia:Articles for deletion/' + wgPageName ) { number = Math.max( number, 1 ); continue; }

var order_re = new RegExp( '^' +							RegExp.escape( 'Wikipedia:Miscellany for deletion/' + wgPageName, true ) +							'\\s*\\(\\s*(\\d+)(?:(?:th|nd|rd|st) nom(?:ination)?)?\\s*\\)\\s*$'					); var match = order_re.exec( title );

// No match; A non-good value if( match == null ) { continue; }

// A match, set number to the max of current number = Math.max( number, Number(match[1]) ); }				self.params.number = num2order( parseInt( number ) + 1); self.params.numbering = number > 0 ? ' (' + self.params.number + ' nomination)' : ''; }

self.statelem.info( 'next in order is Miscellany for deletion/' + wgPageName + self.params.numbering + '');

// Tagging article var query = { 'title': wgPageName, 'action': 'submit' };

var wikipedia_wiki = new Wikipedia.wiki( 'Tagging page with deletion tag', query, twinklexfd.callbacks.mfd.taggingPage ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Discussion page var query = { 'title': 'Wikipedia:Miscellany for deletion/' + wgPageName + this.params.numbering, 'action': 'submit' };

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the discussion page";

wikipedia_wiki = new Wikipedia.wiki( 'Creating page deletion discussion page', query, twinklexfd.callbacks.mfd.discussionPage ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Todays list var query = { 'title': 'Wikipedia:Miscellany for deletion', 'action': 'submit', 'section': 2 };

wikipedia_wiki = new Wikipedia.wiki( 'Adding deletion discussion to todays list', query, twinklexfd.callbacks.mfd.todaysList ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Notification to first contributor var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }			var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };				var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.mfd.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }			var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = self.params; wikipedia_api.post; },		taggingPage: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per memo 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "Nominated for deletion; see Miscellany for deletion/" + wgPageName + self.params.numbering + '.'+ TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{" + ( self.params.number == '' ? "subst:mfd\}\}\n" : 'subst:mfdx|' + self.params.number + "}}\n" ) + form.wpTextbox1.value };			self.post( postData ); },		discussionPage: function( self ) { var form = self.responseXML.getElementById('editform'); 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 deletion discussion page for \[\[" + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{subst:mfd2|pg=" + wgPageName + "|text=" + self.params.reason + " \~\~\~\~\}\}\n" };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform');

var text = form.wpTextbox1.value; var date = new Date;

var month = new Number( date.getUTCMonth + 1 ); var day = new Number( date.getUTCDate ); var year = new Number( date.getUTCFullYear ); var today_date = year.zeroFill( 4 ) + '-' + month.zeroFill( 2 ) + '-' + day.zeroFill( 2 ); var today_regex = new RegExp( "(\\=\\=\\=\\[\\[" + RegExp.escape( today_date ) + "\\]\\]\\=\\=\\=)" ); var new_data = "\n\{\{subst:mfd3|pg=" + wgPageName + self.params.numbering + "\}\}";

if( today_regex.test( text ) ) { // we have a section allready self.statelem.info( 'Found todays section, proceeding to add new entry' ); text = text.replace( today_regex, "$1\n" + new_data ); } else { // we need to create a new section self.statelem.info( 'No section for today found, proceeding to create one' ); var old_text = text; text = text.replace( '-->', "-->\n===\[\[" + today_date + "\]\]===\n" + new_data ); if( text == old_text ) { self.statelem.error( 'failed to find target spot to add the discussion to' ); 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 \[\[Wikipedia:Miscellany for deletion/" + wgPageName + self.params.numbering + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:MFDWarning|1=" + wgPageName + ( self.params.numbering !=  ? '|order= ' + 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': 'MfD nomination of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	},	ifd: { main: function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; self.params.uploader = user; var query = { 'title': 'Wikipedia:Images and media for deletion/' + self.params.date, 'action': 'submit' };

wikipedia_wiki = new Wikipedia.wiki( 'Adding deletion discussion to todays list', query, twinklexfd.callbacks.ifd.todaysList ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the discussion page";

// Notification to first contributor

var query = { 'title': 'User talk:' + self.params.uploader, 'action': 'submit' };			wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + self.params.uploader + ')', query, twinklexfd.callbacks.ifd.userNotification ); wikipedia_wiki.get; },		taggingImage: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "This image is being considered for deletion in accordance with Wikipedia's Deletion policy; See \[\[Wikipedia:Images for deletion#" + wgPageName + '\]\].'+ TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{ifd|log=" + self.params.date + "\}\}\n" + form.wpTextbox1.value };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); 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 discussion for \[\[:" + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': form.wpTextbox1.value + "\n\{\{subst:ifd2|1=" + wgTitle + "|Uploader=" + self.params.uploader + "|Reason=" + self.params.reason + "\}\} \~\~\~\~" };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:idw|1=" + wgPageName + "\}\}"; 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': 'Notification: IfD nomination of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		tagInstancesMain: function( self ) { var xmlDoc = self.responseXML; var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement); var snapshot = xmlDoc.evaluate('//imageusage/iu/@title', xmlDoc, nsResolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

if( snapshot.snapshotLength == 0 ) { return; }

var statusIndicator = new Status('Tagging instances image', '0%'); var total = snapshot.snapshotLength * 2;

var date = new Date; var dateString = date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate;

imageTaggingCounter = 0; var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++imageTaggingCounter/total ) + '%'; obj.update( now ); self.statelem.unlink; if( imageTaggingCounter == total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }			}

var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint; for ( var i = 0; i < snapshot.snapshotLength; ++i ) { var title = snapshot.snapshotItem(i).value; var query = { 'title': title, 'action': 'submit' }				var wikipedia_wiki = new Wikipedia.wiki( "Tagging of " + title, query, twinklexfd.callbacks.ifd.tagInstances ); wikipedia_wiki.params = { title:title, total:total, obj:statusIndicator, date:dateString }; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }		},		tagInstances: function( self ) { var form = self.responseXML.getElementById('editform'); var text = form.wpTextbox1.value; var old_text = text; var wikiPage = new Mediawiki.Page( text );

var tag = "\{\{ifdc|1=Image:" + wgTitle + "|log=" + self.params.date + "\}\}"; wikiPage.addToImageComment( wgTitle, tag );

text = wikiPage.getText; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted; 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': 'Tagging Image:' + wgTitle + " which is up for deletion at Images for deletion" + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	},	pui: { taggingImage: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "This image has been listed on Possibly unfree images because the information on its source or copyright status is disputed; See \[\[Wikipedia:Possibly unfree images#" + wgPageName + '\]\].'+ TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{pui|log=" + self.params.date + "\}\}\n" + form.wpTextbox1.value };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); 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 discussion for \[\[:" + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': form.wpTextbox1.value + "\n\{\{subst:pui2|image=" + wgTitle + "|reason=" + self.params.reason + "\}\} \~\~\~\~" };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:idw-pui|1=" + wgPageName + "\}\} --\~\~\~\~"; 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': 'Notification: PUI posting of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		tagInstancesMain: function( self ) { var xmlDoc = self.responseXML; var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement); var snapshot = xmlDoc.evaluate('//imageusage/iu/@title', xmlDoc, nsResolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

if( snapshot.snapshotLength == 0 ) { return; }			var statusIndicator = new Status('Tagging instances image', '0%'); var total = snapshot.snapshotLength * 2;

var date = new Date; var dateString = date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate;

imageTaggingCounter = 0; var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++imageTaggingCounter/total ) + '%'; obj.update( now ); self.statelem.unlink; if( imageTaggingCounter == total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }			}			var onloaded = onsuccess;

var onloading = function( wikipedia_wiki ) {}

Wikipedia.addCheckpoint; for ( var i = 0; i < snapshot.snapshotLength; ++i ) { var title = snapshot.snapshotItem(i).value; var query = { 'title': title, 'action': 'submit' }				var wikipedia_wiki = new Wikipedia.wiki( "Tagging " + title, query, twinklexfd.callbacks.pui.tagInstances ); wikipedia_wiki.params = { title:title, total:total, obj:statusIndicator, date:dateString }; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }		},		tagInstances: function( self ) { var form = self.responseXML.getElementById('editform'); var text = form.wpTextbox1.value; var old_text = text; var wikiPage = new Mediawiki.Page( text );

var tag = "\{\{puic|1=Image:" + wgTitle + "|log=" + self.params.date + "\}\}"; wikiPage.addToImageComment( wgTitle, tag );

text = wikiPage.getText; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted; 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': 'Tagging Image:' + wgTitle + " which have been listed on Possible unfree images" + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }

},	cfd: { taggingCategory: function( self ) { var form = self.responseXML.getElementById('editform'); var added_data = ""; var summary = ""; switch( self.params.xfdcat ) { case 'cfd': added_data = "\{\{subst:cfd\}\}"; summary = "This category is being considered for deletion in accordance with CDP;" + TwinkleConfig.summaryAd; break; case 'cfm': added_data = "\{\{subst:cfm|" + self.params.target.replace('Category:','') + "\}\}"; summary = "This category is being considered for merging in accordance with CDP;" + TwinkleConfig.summaryAd; break; case 'cfr': added_data = "\{\{subst:cfr|" + self.params.target.replace('Category:','') + "\}\}"; summary = "This category is being considered for renaming in accordance with CDP;" + TwinkleConfig.summaryAd; break; case 'cfc': added_data = "\{\{subst:cfc|" + self.params.target + "\}\}"; summary = "This category is being considered for conversion in accordance with CDP;" + TwinkleConfig.summaryAd; break; }			var postData = { 'wpMinoredit': undefined, // Per the cabal 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': summary, 'wpTextbox1': added_data + "\n" + form.wpTextbox1.value };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); var added_data = ""; var summary = ""; switch( this.params.xfdcat ) { case 'cfd': added_data = "\{\{subst:cfd2|1=" + wgTitle + "|text=" + self.params.reason + " \~\~\~\~\}\}"; summary = "Added delete nomination of " + wgPageName + ";" + TwinkleConfig.summaryAd; break; case 'cfm': added_data = "\{\{subst:cfm2|1=" + wgTitle + "|2=" + self.params.target + "|text=" + self.params.reason + " \~\~\~\~\}\}"; summary = "Added merge nomination of " + wgPageName + ";" + TwinkleConfig.summaryAd; break; case 'cfr': added_data = "\{\{subst:cfr2|1=" + wgTitle + "|2=" + self.params.target + "|text=" + self.params.reason + " \~\~\~\~\}\}"; summary = "Added rename nomination of " + wgPageName + ";" + TwinkleConfig.summaryAd; break; case 'cfc': added_data = "\{\{subst:cfc2|1=" + wgTitle + "|2=" + self.params.target + "|text=" + self.params.reason + " \~\~\~\~\}\}"; summary = "Added convert nomination of " + wgPageName + ";" + TwinkleConfig.summaryAd; break; }			var old_text = form.wpTextbox1.value;

text = old_text.replace( '-->', "-->\n" + added_data ); if( text == old_text ) { self.statelem.error( 'failed to find target spot to add the discussion to' ); 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': summary, 'wpTextbox1': text };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; var intext = ""; switch( self.params.xfdcat ) { case 'cfd': intext = 'for deletion'; break; case 'cfm': intext = 'for merging into \{\{lc|' + self.params.target + "\}\}" ; break; case 'cfr': intext = 'for renaming to \{\{lc|' + self.params.target + "\}\}" ; break; case 'cfc': intext = 'for converting into an article named \{\{lc|' + self.params.target + "\}\}" ; break; }			text += "\n==CfD nomination of " + wgPageName + "==\nI have nominated \{\{lc|" + wgTitle + "\}\} " + intext + ". Your opinions on the matter are welcome; please participate in the discussion by adding your comments at the discussion page. Thank you. \~\~\~\~";

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': 'Notification: CfD nomination of \[\[:' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	},	rfd: { main: function( self ) { var xmlDoc = self.responseXML; var target = xmlDoc.evaluate( '//redirects/r/@to', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; if( !target ) { self.statelem.error( 'no target of this redirect, aborting' ); return; }			self.params.target = target;

// Tagging redirect var query = { 'title': wgPageName, 'action': 'submit' };

wikipedia_wiki = new Wikipedia.wiki( 'Tagging redirect with rfd tag', query, twinklexfd.callbacks.rfd.taggingRedirect ); wikipedia_wiki.followRedirect = false; wikipedia_wiki.get;

var date = new Date; var today = date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate; var query = { 'title': 'Wikipedia:Redirects for discussion/Log/' + today, 'action': 'submit' };

wikipedia_wiki = new Wikipedia.wiki( 'Adding deletion discussion to todays list', query, twinklexfd.callbacks.rfd.todaysList ); wikipedia_wiki.params = self.params; wikipedia_wiki.get;

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the discussion page";

self.params.todaysPage = query['title'];

// Notifying initial contributor var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }			var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };				var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.rfd.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }			var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = self.params; wikipedia_api.post;

},		taggingRedirect: function( self ) { var form = self.responseXML.getElementById('editform'); var postData = { 'wpMinoredit': undefined, // Per 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "This redirect has been listed on Redirects for discussion\]\]." + TwinkleConfig.summaryAd, 'wpTextbox1': "\{\{rfd\}\}\n" + form.wpTextbox1.value };			self.post( postData ); },		todaysList: function( self ) { var form = self.responseXML.getElementById('editform'); var old_text = form.wpTextbox1.value; var text = old_text.replace( /(<\!-- Add new entries directly below this line -->\n+)/, "$1\{\{subst:rfd2|redirect="+ wgPageName + "|target=" + self.params.target + "|text=" + self.params.reason.toUpperCaseFirstChar +"\}\} \~\~\~\~\n" ); if( text == old_text ) { self.statelem.error( 'failed to find target spot to add the discussion to.' ); 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 " + wgPageName + '.' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); },		userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n==RfD nomination of " + wgPageName + "==\nI have nominated " + ln( wgNamespaceNumber, wgTitle ) + " for discussion. Your opinions on the matter are welcome; please participate in the discussion by adding your comments at the discussion page. Thank you. \~\~\~\~"; 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': 'Notification: RFD posting of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };			self.post( postData ); }	} }

twinklexfd.callback.evaluate = function(e) {

wgPageName = wgPageName.replace( /_/g, ' ' ); // for queen/king/whatever and country!

var type = e.target.category.value; var reason = e.target.xfdreason.value; if( type in {'afd':,'cfd':} ) { var xfdcat = e.target.xfdcat.value; }	if( type == 'ifd' ) { var pui = e.target.pui.checked; }

Status.init( e.target );

if( type == null ) { Status.error( 'Error', 'no action given' ); return; }

switch( type ) { case 'afd': // AFD var query = { 'action': 'query', 'list': 'allpages', 'apprefix': 'Articles for deletion/' + wgPageName, 'apnamespace': 4, 'apfilterredir': 'nonredirects', 'aplimit': userIsInGroup( 'sysop' ) ? 5000 : 500		};		var wikipedia_api = new Wikipedia.api( 'Tagging article with deletion tag', query, twinklexfd.callbacks.afd.main ); wikipedia_api.params = { reason:reason, xfdcat:xfdcat }; wikipedia_api.post; break; case 'tfd': // TFD

Wikipedia.addCheckpoint; // Tagging article var query = { 'title': wgPageName, 'action': 'submit' };		wikipedia_wiki = new Wikipedia.wiki( 'Tagging template with deletion tag', query, twinklexfd.callbacks.tfd.taggingTemplate ); wikipedia_wiki.get;

// Adding discussion var date = new Date;

query = { 'title': 'Wikipedia:Templates for deletion/Log/' + date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate, 'action': 'submit', 'section': 1 };

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the list of today";

wikipedia_wiki = new Wikipedia.wiki( 'Adding discussion to todays list', query, twinklexfd.callbacks.tfd.todaysList ); wikipedia_wiki.params = { reason:reason }; wikipedia_wiki.get;

var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }		var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };			var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.tfd.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }		var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = self.params; wikipedia_api.post;

Wikipedia.removeCheckpoint; break; case 'mfd': // MFD

var query = { 'action': 'query', 'list': 'allpages', 'apprefix': 'Miscellany for deletion/' + wgPageName, 'apnamespace': 4, 'apfilterredir': 'nonredirects', 'aplimit': userIsInGroup( 'sysop' ) ? 5000 : 500		};		var wikipedia_api = new Wikipedia.api( 'Quering allpages', query, twinklexfd.callbacks.mfd.main ); wikipedia_api.params = { reason:reason, xfdcat:xfdcat }; wikipedia_api.post; break; case 'ifd': // IFD

var date = new Date; var dateString = date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate; var params = { reason: reason, date: dateString };

Wikipedia.addCheckpoint; if( pui ) { // Tagging image var query = { 'title': wgPageName, 'action': 'submit' };

var wikipedia_wiki = new Wikipedia.wiki( 'Tagging image with PUI tag', query, twinklexfd.callbacks.pui.taggingImage ); wikipedia_wiki.params = params; wikipedia_wiki.get; // Adding discussion

query = { 'title': 'Wikipedia:Possibly unfree images/' + dateString, 'action': 'submit' };

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = query['title']; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the list of today";

wikipedia_wiki = new Wikipedia.wiki( 'Adding discussion to todays list', query, twinklexfd.callbacks.pui.todaysList ); wikipedia_wiki.params = params; wikipedia_wiki.get;

var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }			var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };				var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.pui.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }			var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = params; wikipedia_api.post;

Wikipedia.removeCheckpoint;

// adding tag to captions var query = { 'action': 'query', 'list': 'imageusage', 'iutitle': wgPageName, 'iulimit': userIsInGroup( 'sysop' ) ? 5000 : 500 // 500 is max for normal users, 5000 for bots and sysops };

var wikipedia_api = new Wikipedia.api( 'Grabbing image links', query, twinklexfd.callbacks.pui.tagInstancesMain ); wikipedia_api.post;

} else { // Tagging image var query = { 'title': wgPageName, 'action': 'submit' };

var wikipedia_wiki = new Wikipedia.wiki( 'Tagging image with deletion tag', query, twinklexfd.callbacks.ifd.taggingImage ); wikipedia_wiki.params = params; wikipedia_wiki.get;

// Contributor specific edits var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }			var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, twinklexfd.callbacks.ifd.main ); wikipedia_api.params = params; wikipedia_api.post;

// adding tag to captions var query = { 'action': 'query', 'list': 'imageusage', 'iutitle': wgPageName, 'iulimit': userIsInGroup( 'sysop' ) ? 5000 : 500 // 500 is max for normal users, 5000 for bots and sysops };

var wikipedia_api = new Wikipedia.api( 'Grabbing image links', query, twinklexfd.callbacks.ifd.tagInstancesMain ); wikipedia_api.post; }		Wikipedia.removeCheckpoint; break; case 'cfd': Wikipedia.addCheckpoint; if( e.target.xfdtarget ) { var target = e.target.xfdtarget.value.replace( /^\:?Category\:/, '' ); } else { var target = ''; }

var date = new Date; var todaysPage = 'Wikipedia:Categories for discussion/Log/' + date.getUTCFullYear + ' ' + date.getUTCMonthName + ' ' + date.getUTCDate;

// Updating data for the action completed event Wikipedia.actionCompleted.redirect = todaysPage; Wikipedia.actionCompleted.notice = "Nomination completed, redirecting now to the discussion page";

// Tagging category

var query = { 'title': wgPageName, 'action': 'submit' };		var params = { reason:reason, xfdcat:xfdcat, target:target };

var wikipedia_wiki = new Wikipedia.wiki( 'Tagging category with tag', query, twinklexfd.callbacks.cfd.taggingCategory ); wikipedia_wiki.params = params; wikipedia_wiki.get;

// Todays list var query = { 'title': todaysPage, 'action': 'submit', 'section': 2 };

var wikipedia_wiki = new Wikipedia.wiki( 'Adding discussion to todays list', query, twinklexfd.callbacks.cfd.todaysList ); wikipedia_wiki.params = params; wikipedia_wiki.get;

// Notification to first contributor var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }		var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };			var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinklexfd.callbacks.cfd.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }		var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = { xfdcat:xfdcat, target:target, todaysPage:todaysPage }; wikipedia_api.post; Wikipedia.removeCheckpoint; break; case 'rfd': var query = { 'action': 'query', 'titles': wgPageName, 'redirects': true };		var wikipedia_api = new Wikipedia.api( 'Quering redirect', query, twinklexfd.callbacks.rfd.main ); wikipedia_api.params = { reason:reason }; wikipedia_api.post; break; } }

title: User:Flewis/twinklexfd.js


text:
User:Flewis/twinkleimage.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"; }

if( typeof( TwinkleConfig.notifyUserOnDeli ) == 'undefined' ) { TwinkleConfig.notifyUserOnDeli = true; }

function twinkleimage { if( wgNamespaceNumber == 6 ) { mw.util.addPortletLink( 'p-cactions', (twinkleConfigExists ? "javascript:twinkleimage.callback" : 'javascript:alert("Your account is too new to use Twinkle.");'), "di", "tw-di", "Nominate image for relative speedy deletion", ""); } }

$(twinkleimage);

twinkleimage.callback = function twinkleimageCallback { var Window = new SimpleWindow( 600, 300 ); Window.setTitle( "Image for pseudo-speedy deletion" ); var form = new QuickForm( twinkleimage.callback.evaluate ); form.append( {			type: 'checkbox',			list: [				{					label: 'Notify original uploader',					value: 'notify',					name: 'notify',					tooltip: 'Uncheck this if you are planning to make multiple nominations from the same user, and dont want your ass to be spanked.',					checked: TwinkleConfig.notifyUserOnDeli				}			]		}	); var field = form.append( {			type: 'field',			label: 'Type of action wanted'		} ); field.append( {			type: 'radio',			name: 'type',			event: twinkleimage.callback.choice,			list: [				{					label: 'No source',					value: 'no source',					checked: true,					tooltip: 'Image or media has no source information'				},				{					label: 'No license',					value: 'no license',					tooltip: 'Image or media does not have information on its copyright status'				},				{					label: 'No fair use rationale',					value: 'no fair use rationale',					tooltip: 'Image or media is claimed to be used under Wikipedia\'s fair use policy but has no explanation as to why it is permitted under the policy'				},				{					label: 'Disputed fair use rationale',					value: 'disputed fair use rationale',					tooltip: 'Image or media has a fair use rationale that is disputed'				},

{					label: 'Orphaned fair use', value: 'orphaned fair use', tooltip: 'Image or media is unlicensed for use on Wikipedia and allowed only under a claim of fair use per Wikipedia:Non-free content, but it is not used in any articles' },				{					label: 'Replaceable fair use', value: 'replaceable fair use', tooltip: 'Image or media may fail Wikipedia\'s first non-free content criterion in that it illustrates a subject for which a free image might reasonably be found or created that adequately provides the same information' }			]		} );	form.append( { type: 'div', label: 'Work area', name: 'work_area' } );	var result = form.render;	Window.setContent( result );	Window.display;

// We must init the var evt = document.createEvent( "Event" ); evt.initEvent( 'change', true, true ); result.type[0].dispatchEvent( evt ); }

twinkleimage.callback.choice = function twinkleimageCallbackChoose(event) { var value = event.target.value; var root = event.target.form; var work_area = new QuickForm.element( { 			type: 'div',			name: 'work_area'		} );

switch( value ) { case 'disputed fair use rationale': work_area.append( {				type: 'textarea',				name: 'reason',				label: 'Concern: '			} ); break; case 'orphaned fair use': work_area.append( {				type: 'input',				name: 'replacement',				label: 'Replacement: '			} ); break; case 'replaceable fair use': work_area.append( {				type: 'checkbox',				name: 'old_image',				list: [					{						label: 'Old image',						tooltip: 'Image was uploaded before 2006-07-13'					}				]			} ); break; }	work_area.append( { type:'submit' } ); work_area = work_area.render; root.replaceChild( work_area, root.lastChild ); }

twinkleimage.callback.evaluate = function twinkleimageCallbackEvaluate(event) { var notify = event.target.notify.checked; var types = event.target.type; for( var i = 0; i < types.length; ++i ) { if( types[i].checked ) { var type = types[i].value; break; }	}	if( event.target.reason ) { var reason = event.target.reason.value; }	if( event.target.replacement ) { var replacement = event.target.replacement.value; }	if( event.target.old_image ) { var old_image = event.target.old_image.checked; }

var params = { reason: reason, old_image: old_image, type: type, replacement: replacement }; Status.init( event.target ); // Tagging image var query = { 'title': wgPageName, 'action': 'submit' };

var wikipedia_wiki = new Wikipedia.wiki( 'Tagging image with deletion tag', query, twinkleimage.callbacks.taggingImage ); wikipedia_wiki.params = params; wikipedia_wiki.get;

// Notifying uploader if( notify ) { var query = { 'action': 'query', 'prop': 'revisions', 'titles': wgPageName, 'rvlimit': 1, 'rvprop': 'user', 'rvdir': 'newer' }		var callback = function( self ) { var xmlDoc = self.responseXML; var user = xmlDoc.evaluate( '//rev/@user', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; var query = { 'title': 'User talk:' + user, 'action': 'submit' };			var wikipedia_wiki = new Wikipedia.wiki( 'Notifying of initial contributor (' + user + ')', query, twinkleimage.callbacks.userNotification ); wikipedia_wiki.params = self.params; wikipedia_wiki.get; }		var wikipedia_api = new Wikipedia.api( 'Grabbing data of initial contributor', query, callback ); wikipedia_api.params = params; wikipedia_api.post; } else { // No auto-notifiaction, display what was going to be added. var noteData = document.createElement( 'pre' ); noteData.appendChild( document.createTextNode( "\{\{subst:di-" + type + "-notice|1=" + wgTitle + "\}\} \~\~\~\~" ) ); Status.info( 'Notification', [ 'Following/Similar data should be pasted to the original uploader:', document.createElement( 'br' ), noteData ] );

}

// adding tag to captions var query = { 'action': 'query', 'list': 'imageusage', 'iutitle': wgPageName, 'iulimit': userIsInGroup( 'sysop' ) ? 5000 : 500 // 500 is max for normal users, 5000 for bots and sysops };

var wikipedia_api = new Wikipedia.api( 'Grabbing image links', query, twinkleimage.callbacks.tagInstancesMain ); wikipedia_api.params = params; wikipedia_api.post; }

twinkleimage.callbacks = { taggingImage: function( self ) { var form = self.responseXML.getElementById('editform'); var text = ''; switch( self.params.type ) { case 'disputed fair use rationale': text += "\{\{di-disputed fair use rationale|date=\{\{subst:#time:j F Y\}\}" + ( self.params.reason ? "|concern=" + self.params.reason : '') + "\}\}"; break; case 'orphaned fair use': text += "\{\{di-orphaned fair use|date=\{\{subst:#time:j F Y\}\}" + ( self.params.replacement ? "|replacement=" + self.params.replacement : '') + "\}\}"; break; case 'replaceable fair use': text += "\{\{di-replaceable fair use|date=\{\{subst:#time:j F Y\}\}" + ( self.params.old_image ? "|old image=yes" : '') + "\}\}"; break; default: text += "\{\{di-" + self.params.type + "|date=\{\{subst:#time:j F Y\}\}\}\}"; break; }		var postData = { 'wpMinoredit': undefined, // Per 'wpWatchthis': form.wpWatchthis.checked ? '' : undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': "This image is up for deletion per \[\[WP:CSD\]\]." + TwinkleConfig.summaryAd, 'wpTextbox1': text + form.wpTextbox1.value };		self.post( postData ); },	userNotification: function( self ) { var form = self.responseXML.getElementById( 'editform' ); var text = form.wpTextbox1.value; text += "\n\{\{subst:di-" + self.params.type + "-notice|1=" + wgTitle + "\}\} \~\~\~\~"; 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': 'Notification: Deletion of \[\[' + wgPageName + '\]\].' + TwinkleConfig.summaryAd, 'wpTextbox1': text };		self.post( postData ); },	tagInstancesMain: function( self ) { var statusIndicator = new Status('Tagging instances image', '0%'); var xmlDoc = self.responseXML; var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement); var snapshot = xmlDoc.evaluate('//imageusage/iu/@title', xmlDoc, nsResolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

var total = snapshot.snapshotLength * 2;

imageTaggingCounter = 0; var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++imageTaggingCounter/total ) + '%'; obj.update( now ); self.statelem.unlink; if( imageTaggingCounter == total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }		}		var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint; for ( var i = 0; i < snapshot.snapshotLength; ++i ) { var title = snapshot.snapshotItem(i).value; var query = { 'title': title, 'action': 'submit' }			var wikipedia_wiki = new Wikipedia.wiki( "Tagging " + title, query, twinkleimage.callbacks.tagInstances ); wikipedia_wiki.params = { title:title, total:total, obj:statusIndicator, days: self.params.old_image ? 2 : 7 };			wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }	},	tagInstances: function( self ) { var form = self.responseXML.getElementById('editform'); var text = form.wpTextbox1.value; var old_text = text; var wikiPage = new Mediawiki.Page( text );

var tag = "\{\{deletable image-caption|1=\{\{subst:#time:l, j F Y| + " + self.params.days + " days\}\}\}\}"; wikiPage.addToImageComment( wgTitle, tag );

text = wikiPage.getText; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted( self ); return; }		var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Tagging Image:' + wgTitle + " which is up for deletion per CSD " + TwinkleConfig.summaryAd, 'wpTextbox1': text };		self.post( postData ); } }

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: User:Flewis/twinkleimage.js


text:
User:Flewis/twinkleunlink.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"; }

function getChecked2( nodelist ) { if( !( nodelist instanceof NodeList ) ) { return nodelist.checked ? [ nodelist.value ] : []; }	var result = []; for(var i = 0; i < nodelist.length; ++i ) { if( nodelist[i].checked ) { result.push( nodelist[i].value ); }	}	return result; }

function twinkleunlink { if( wgNamespaceNumber < 0 ) { return; }	mw.util.addPortletLink( 'p-cactions', "javascript:twinkleunlink.callback", "unlink", "tw-unlink", "Unlink backlinks", ""); } $(twinkleunlink);

twinkleunlink.callback = function twinklesunlinkCallback { var Window = new SimpleWindow( 800, 400 ); Window.setTitle( "Unlink backlinks" );

var form = new QuickForm( twinkleunlink.callback.evaluate ); form.append( {			type: 'textarea',			name: 'reason',			label: 'Reason: '		} );

if(wgNamespaceNumber == Namespace.IMAGE) { var query = { 'action': 'query', 'list': [ 'backlinks', 'imageusage' ], 'bltitle': wgPageName, 'iutitle': wgPageName, 'bllimit': userIsInGroup( 'sysop' ) ? 5000 : 500, // 500 is max for normal users, 5000 for bots and sysops 'iulimit': userIsInGroup( 'sysop' ) ? 5000 : 500, // 500 is max for normal users, 5000 for bots and sysops 'blnamespace': [0, 100] // Main namespace and portal namespace only, keep on talk pages. };	} else { var query = { 'action': 'query', 'list': 'backlinks', 'bltitle': wgPageName, 'bllimit': userIsInGroup( 'sysop' ) ? 5000 : 500, // 500 is max for normal users, 5000 for bots and sysops 'blnamespace': [0, 100] // Main namespace and portal namespace only, keep on talk pages. };	}	var wikipedia_api = new Wikipedia.api( 'Grabbing backlinks', query, twinkleunlink.callbacks.display.backlinks ); wikipedia_api.params = { form:form, Window:Window, image: wgNamespaceNumber == Namespace.IMAGE }; wikipedia_api.post;

var root = document.createElement( 'div' ); Status.init( root ); Window.setContent( root ); Window.display; }

twinkleunlink.callback.evaluate = function twinkleunlinkCallbackEvaluate(event) { wgPageName = wgPageName.replace( /_/g, ' ' ); // for queen/king/whatever and country!

var reason = event.target.reason.value; if( event.target.backlinks ) { var backlinks = getChecked( event.target.backlinks ); }	if( event.target.imageusage ) { var imageusage = getChecked( event.target.imageusage ); }	Status.init( event.target );

if( imageusage ) { var statusIndicator = new Status('Unlinking instances image', '0%'); var total = imageusage.length * 2;

var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++(self.params.current)/total ) + '%'; obj.update( now ); self.statelem.unlink; if( self.params.current >= total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }		}		var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint;

if( imageusage.length == 0 ) { statusIndicator.info( '100% (completed)' ); Wikipedia.removeCheckpoint; return; }		var params = { reason: reason, obj: statusIndicator, current: 0, total: total }; for ( var i = 0; i < imageusage.length; ++i ) { var title = imageusage[i]; var query = { 'title': title, 'action': 'submit' }			var wikipedia_wiki = new Wikipedia.wiki( "Unlinking on " + title, query, twinkleunlink.callbacks.unlinkImageInstances ); wikipedia_wiki.params = clone( params ); wikipedia_wiki.params.title = title; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }	}

if( backlinks ) { var statusIndicator = new Status('Unlinking instances image', '0%'); var total = backlinks.length * 2;

var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++(self.params.current)/total ) + '%'; obj.update( now ); self.statelem.unlink; if( self.params.current >= total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }		}		var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint;

if( backlinks.length == 0 ) { statusIndicator.info( '100% (completed)' ); Wikipedia.removeCheckpoint; return; }		var params = { reason: reason, obj: statusIndicator, current: 0, total: total }; for ( var i = 0; i < backlinks.length; ++i ) { var title = backlinks[i]; var query = { 'title': title, 'action': 'submit' }			var wikipedia_wiki = new Wikipedia.wiki( "Unlinking on " + title, query, twinkleunlink.callbacks.unlinkBacklinks ); wikipedia_wiki.params = clone( params ); wikipedia_wiki.params.title = title; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }	} } twinkleunlink.callbacks = { display: { backlinks: function( self ) { var xmlDoc = self.responseXML; if( self.params.image ) { var imageusage = xmlDoc.evaluate('//query/imageusage/iu/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null ); var list = []; for ( var i = 0; i < imageusage.snapshotLength; ++i ) { var title = imageusage.snapshotItem(i).value; list.push( { label: title, value: title, checked: true } ); }				self.params.form.append( { type:'header', label: 'Image usage' } ); self.params.form.append( {						type: 'checkbox',						name: 'imageusage',						list: list					}				); }

var backlinks = xmlDoc.evaluate('//query/backlinks/bl/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null ); if( backlinks.snapshotLength > 0 ) { var list = []; for ( var i = 0; i < backlinks.snapshotLength; ++i ) { var title = backlinks.snapshotItem(i).value; list.push( { label: title, value: title, checked: true } ); }				self.params.form.append( { type:'header', label: 'Backlinks' } ); self.params.form.append( {						type: 'checkbox',						name: 'backlinks',						list: list					}				); }

self.params.form.append( { type:'submit' } );

var result = self.params.form.render; self.params.Window.setContent( result ); }	},	unlinkBacklinks: function( self ) { var form = self.responseXML.getElementById('editform'); var text = form.wpTextbox1.value; var old_text = text; var wikiPage = new Mediawiki.Page( text ); wikiPage.removeLink( wgPageName );

text = wikiPage.getText; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted( self ); return; }		var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Removing backlinks to ' + wgTitle + " because \"" + self.params.reason.toUpperCaseFirstChar + "\";" + TwinkleConfig.deletionSummaryAd, 'wpTextbox1': text };		self.post( postData ); },	unlinkImageInstances: function( self ) { var form = self.responseXML.getElementById('editform'); var text = form.wpTextbox1.value; var old_text = text; var wikiPage = new Mediawiki.Page( text ); wikiPage.commentOutImage( wgTitle, 'Commented out' );

text = wikiPage.getText; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted( self ); return; }		var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Removing instances of image ' + wgTitle + " beacuse \"" + self.params.reason.toUpperCaseFirstChar + "\";" + TwinkleConfig.deletionSummaryAd, 'wpTextbox1': text };		self.post( postData ); } }

title: User:Flewis/twinkleunlink.js


text:
User:Flewis/twinkledelimages.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.deletionSummaryAd (string) If ad should be added or not to deletion summary, default TWINKLE if( typeof( TwinkleConfig.deletionSummaryAd ) == 'undefined' ) { TwinkleConfig.deletionSummaryAd = " using TW"; }

/** TwinkleConfig.deliChunks (integer) How many images should be processed at a time if( typeof( TwinkleConfig.deliChunks ) == 'undefined' ) { TwinkleConfig.deliChunks = 500; }

/** TwinkleConfig.deliMax (integer) How many images should be processed maximum if( typeof( TwinkleConfig.deliMax ) == 'undefined' ) { TwinkleConfig.deliMax = 5000; } function twinkledeli { if( wgNamespaceNumber < 0 || wgCurRevisionId == false ) { return; }	if( userIsInGroup( 'sysop' ) ) {

mw.util.addPortletLink( 'p-cactions', "javascript:twinkledeli.callback", "deli", "tw-deli", "Delete image found on page", ""); } } $(twinkledeli);

twinkledeli.unlinkCache = {}; twinkledeli.callback = function twinklesdeliCallback { var Window = new SimpleWindow( 800, 400 ); Window.setTitle( "Batch image deletion" );

var form = new QuickForm( twinkledeli.callback.evaluate ); form.append( {			type: 'checkbox',			list: [				{ 					label: 'Delete images',					name: 'delete_image',					value: 'delete',					checked: true				},				{					label: 'Remove image instances to the image',					name: 'unlink_image',					value: 'unlink',					checked: true				}			]		} ); form.append( {			type: 'textarea',			name: 'reason',			label: 'Reason: '		} ); if( wgNamespaceNumber == Namespace.CATEGORY ) { var query = { 'action': 'query', 'generator': 'categorymembers', 'gcmtitle': wgPageName, 'gcmnamespace': Namespace.IMAGE, 'gcmlimit' : TwinkleConfig.deliMax, 'prop': [ 'imageinfo', 'categories', 'revisions' ], 'grvlimit': 1, 'grvprop': [ 'user' ] };	} else { var query = { 'action': 'query', 'generator': 'images', 'titles': wgPageName, 'prop': [ 'imageinfo', 'categories', 'revisions' ], 'grvlimit': 1, 'grvprop': [ 'user' ] };	}	var wikipedia_api = new Wikipedia.api( 'Grabbing images', query, function( self ) {			var xmlDoc = self.responseXML;			var snapshot = xmlDoc.evaluate('//page[@imagerepository="local"]', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );			var list = [];			for ( var i = 0; i < snapshot.snapshotLength; ++i ) {				var object = snapshot.snapshotItem(i);				var image = xmlDoc.evaluate( '@title', object, null, XPathResult.STRING_TYPE, null ).stringValue;				var user = xmlDoc.evaluate( 'imageinfo/ii/@user', object, null, XPathResult.STRING_TYPE, null ).stringValue;				var last_edit = xmlDoc.evaluate( 'revisions/rev/@user', object, null, XPathResult.STRING_TYPE, null ).stringValue;

var disputed = xmlDoc.evaluate( 'boolean(categories/cl[@title="Category:Contested candidates for speedy deletion"])', object, null, XPathResult.BOOLEAN_TYPE, null ).booleanValue || user == last_edit; list.push( {label:(i+1) + ": " + image + ' (' + user + ')[' + last_edit + ']' + ( disputed ? ' DISPUTED' : '' ), value:image, checked:!disputed }); }			self.params.form.append( {					type: 'checkbox',					name: 'images',					list: list				}			) self.params.form.append( { type:'submit' } );

var result = self.params.form.render; self.params.Window.setContent( result );

} );

wikipedia_api.params = { form:form, Window:Window }; wikipedia_api.post; var root = document.createElement( 'div' ); Status.init( root ); Window.setContent( root ); Window.display; }

twinkledeli.currentDeleteCounter = 0; twinkledeli.currentUnlinkCounter = 0; twinkledeli.currentdeletor; twinkledeli.callback.evaluate = function twinkledeliCallbackEvaluate(event) { wgPageName = wgPageName.replace( /_/g, ' ' ); // for queen/king/whatever and country! var images = event.target.getChecked( 'images' ); var reason = event.target.reason.value; var delete_image = event.target.delete_image.checked; var unlink_image = event.target.unlink_image.checked; if( ! reason ) { return; }	Status.init( event.target ); function toCall( work ) { if( work.length == 0 && twinkledeli.currentDeleteCounter <= 0 && twinkledeli.currentUnlinkCounter <= 0 ) { Status.info( 'work done' ); window.clearInterval( twinkledeli.currentdeletor ); Wikipedia.removeCheckpoint; return; } else if( twinkledeli.currentDeleteCounter <= 0 && twinkledeli.currentUnlinkCounter <= 0 ) { twinkledeli.unlinkCache = []; // Clear the cache var images = work.shift; twinkledeli.currentDeleteCounter = images.length; // can be less than the number of elements in deliChunks for( var i = 0; i < images.length; ++i ) { var image = images[i]; var query = { 'action': 'query', 'titles': image }				var wikipedia_api = new Wikipedia.api( 'Checking if image ' + image + ' exists', query, twinkledeli.callbacks.main ); wikipedia_api.params = { image:image, reason:reason, unlink_image:unlink_image, delete_image:delete_image }; wikipedia_api.post; }		}	}	var work = images.chunk( TwinkleConfig.deliChunks ); Wikipedia.addCheckpoint; twinkledeli.currentdeletor = window.setInterval( toCall, 1000, work ); } twinkledeli.callbacks = { main: function( self ) { var xmlDoc = self.responseXML; var normal = xmlDoc.evaluate( '//normalized/n/@to', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; if( normal ) { self.params.image = normal; }		var exists = xmlDoc.evaluate( 'boolean(//pages/page[@title="' + self.params.image.replace( /"/g, '\\"') + '" and not(@missing)])', xmlDoc, null, XPathResult.BOOLEAN_TYPE, null ).booleanValue;

if( ! exists ) { self.statelem.error( "It seems that the page doesn't exists, perhaps it has already been deleted" ); return; }		if( self.params.unlink_image ) { var query = { 'action': 'query', 'list': 'imageusage', 'titles': self.params.image, 'iulimit': userIsInGroup( 'sysop' ) ? 5000 : 500 // 500 is max for normal users, 5000 for bots and sysops };			var wikipedia_api = new Wikipedia.api( 'Grabbing image links', query, twinkledeli.callbacks.unlinkImageInstancesMain ); wikipedia_api.params = self.params; wikipedia_api.post; }		if( self.params.delete_image ) { var query = { 'title': self.params.image, 'action': 'delete' };			var wikipedia_wiki = new Wikipedia.wiki( 'Deleting image ' + self.params.image, query, twinkledeli.callbacks.deleteImage, function( self ) { 					--twinkledeli.currentDeleteCounter;					var link = document.createElement( 'a' );					link.setAttribute( 'href', 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_wiki.params = self.params;			wikipedia_wiki.followRedirect = false;			wikipedia_wiki.get;				}	},	deleteImage: function( self ) {		var form = this.responseXML.getElementById( 'deleteconfirm' );		if( ! form ) { // Hell, image deletion is b0rked :( form = this.responseXML.getElementsByTagName( 'form' )[0]; var postData = { 'wpDeleteReasonList': 'other', 'wpReason': "Deleted because \"" + self.params.reason + "\"." + TwinkleConfig.deletionSummaryAd, 'wpEditToken': form.wpEditToken.value }			self.post( postData ); } else {

var postData = { 'wpWatch': form.wpWatch.checked ? '' : undefined, 'wpDeleteReasonList': 'other', 'wpReason': "Deleted because \"" + self.params.reason + "\"." + TwinkleConfig.deletionSummaryAd, 'wpEditToken': form.wpEditToken.value }			self.post( postData ); }	},	unlinkImageInstancesMain: function( self ) { var xmlDoc = self.responseXML; var snapshot = xmlDoc.evaluate('//imageusage/iu/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

if( snapshot.snapshotLength == 0 ) { --twinklebatchdelete.currentUnlinkCounter; return; }

var statusIndicator = new Status('Unlinking instances image', '0%');

var total = snapshot.snapshotLength * 2;

var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++(self.params.current)/total ) + '%'; obj.update( now ); self.statelem.unlink; if( self.params.current >= total ) { obj.info( now + ' (completed)' ); --twinklebatchdelete.currentUnlinkCounter; Wikipedia.removeCheckpoint;

}		}		var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint; if( snapshot.snapshotLength == 0 ) { statusIndicator.info( '100% (completed)' ); --twinklebatchdelete.currentUnlinkCounter; Wikipedia.removeCheckpoint; return; }		self.params.total = total; self.params.obj = statusIndicator; self.params.current =  0;

for ( var i = 0; i < snapshot.snapshotLength; ++i ) { var title = snapshot.snapshotItem(i).value; var query = { 'title': title, 'action': 'submit' }			var wikipedia_wiki = new Wikipedia.wiki( "Unlinking on " + title, query, twinkledeli.callbacks.unlinkImageInstances ); var params = clone( self.params ); params.title = title;

wikipedia_wiki.params = params; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.get; }	},	unlinkImageInstances: function( self ) { var image = self.params.image.replace( /^Image:/, '' ); var form = self.responseXML.getElementById('editform'); var text;

if( self.params.title in twinkledeli.unlinkCache ) { text = twinkledeli.unlinkCache[ self.params.title ]; } else { text = form.wpTextbox1.value; }		var old_text = text; var wikiPage = new Mediawiki.Page( text ); wikiPage.commentOutImage( image, 'Commented out because image was deleted' );

text = wikiPage.getText; twinkledeli.unlinkCache[ self.params.title ] = text; if( text == old_text ) { // Nothing to do, return self.onsuccess( self ); Wikipedia.actionCompleted( self ); return; }		var postData = { 'wpMinoredit': form.wpMinoredit.checked ? '' : undefined, 'wpWatchthis': undefined, 'wpStarttime': form.wpStarttime.value, 'wpEdittime': form.wpEdittime.value, 'wpAutoSummary': form.wpAutoSummary.value, 'wpEditToken': form.wpEditToken.value, 'wpSummary': 'Removing instance of image ' + image + " that has been deleted because \"" + self.params.reason + "\")" + "; " + TwinkleConfig.deletionSummaryAd,			'wpTextbox1': text		};		self.post( postData );	} }

title: User:Flewis/twinkledelimages.js


text:
User:Flewis/twinkledeprod.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.deletionSummaryAd (string) If ad should be added or not to deletion summary, default TWINKLE */ if( typeof( TwinkleConfig.deletionSummaryAd ) == 'undefined' ) { TwinkleConfig.deletionSummaryAd = " using TW"; }

/** TwinkleConfig.proddeleteChunks (integer) How many pages should be processed at a time */ if( typeof( TwinkleConfig.proddeleteChunks ) == 'undefined' ) { TwinkleConfig.proddeleteChunks = 50; } function twinkleproddelete { if( wgNamespaceNumber != Namespace.CATEGORY || ! userIsInGroup( 'sysop' ) || ! /^Category:Proposed_deletion_as_of/.test(wgPageName) ) { return; }	mw.util.addPortletLink( 'p-cactions', "javascript:twinkleproddelete.callback", "deprod", "tw-deprod", "Delete prod pages found in this category", ""); } $(twinkleproddelete);

function getChecked( nodelist ) { if( !( nodelist instanceof NodeList ) ) { return nodelist.checked ? [ nodelist.value ] : []; }	var result = []; for(var i = 0; i < nodelist.length; ++i ) { if( nodelist[i].checked ) { result.push( nodelist[i].value ); }	}	return result; }

twinkleproddelete.unlinkCache = {}; twinkleproddelete.concerns = {}; twinkleproddelete.callback = function twinklesproddeleteCallback { var Window = new SimpleWindow( 800, 400 ); Window.setTitle( "PROD cleaning" );

var form = new QuickForm( twinkleproddelete.callback.evaluate );

var query = { 'action': 'query', 'generator': 'categorymembers', 'gcmtitle': wgPageName, 'gcmlimit' : 5000, // the max for sysops 'prop': [ 'categories', 'revisions' ], 'rvprop': [ 'content' ] };

var wikipedia_api = new Wikipedia.api( 'Grabbing pages', query, function( self ) {			var xmlDoc = self.responseXML;			var snapshot = xmlDoc.evaluate('//page[@ns != "' + Namespace.IMAGE + '"]', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );			var list = [];			for ( var i = 0; i < snapshot.snapshotLength; ++i ) {				var object = snapshot.snapshotItem(i);				var page = xmlDoc.evaluate( '@title', object, null, XPathResult.STRING_TYPE, null ).stringValue;				var content = xmlDoc.evaluate( 'revisions/rev', object, null, XPathResult.STRING_TYPE, null ).stringValue;				var prod_re = /[Dd]ated[ _]prod/;				var index = content.indexOf( '\{\{dated prod' ); //\}\}				var concern = ;				if( index != -1 ) {					var parsed = Mediawiki.Template.parse( content, index );					var concern = parsed.parameters.concern || ;				}				list.push( {label:page + ' (' + concern + ')', value:page, checked:concern != '' }); twinkleproddelete.concerns[page] = concern; }			self.params.form.append( {					type: 'checkbox',					name: 'pages',					list: list				}			) self.params.form.append( { type:'submit' } );

var result = self.params.form.render; self.params.Window.setContent( result );

} );

wikipedia_api.params = { form:form, Window:Window }; wikipedia_api.post; var root = document.createElement( 'div' ); Status.init( root ); Window.setContent( root ); Window.display; }

twinkleproddelete.currentDeleteCounter = 0; twinkleproddelete.currentUnlinkCounter = 0; twinkleproddelete.currentdeletor; twinkleproddelete.callback.evaluate = function twinkleproddeleteCallbackEvaluate(event) { wgPageName = wgPageName.replace( /_/g, ' ' ); // for queen/king/whatever and country! var pages = getChecked( event.target.pages ); Status.init( event.target ); function toCall( work ) { if( work.length == 0 ) { Status.info( 'work done' ); window.clearInterval( twinkleproddelete.currentdeletor ); Wikipedia.removeCheckpoint; return; } else if( twinkleproddelete.currentDeleteCounter <= 0 || twinkleproddelete.currentUnlinkCounter <= 0 ) { twinkleproddelete.currentcounter = TwinkleConfig.proddeleteChunks; twinkleproddelete.unlinkCache = []; // Clear the cache var pages = work.pop; for( var i = 0; i < pages.length; ++i ) { var page = pages[i]; var query = { 'action': 'query', 'prop': 'revisions', 'rvprop': [ 'content' ], 'rvlimit': 1, 'titles': page }				var wikipedia_api = new Wikipedia.api( 'Checking if page ' + page + ' exists', query, twinkleproddelete.callbacks.main ); wikipedia_api.params = { page:page, reason: twinkleproddelete.concerns[page] }; wikipedia_api.post; }		}	}	var work = pages.chunk( TwinkleConfig.proddeleteChunks ); Wikipedia.addCheckpoint; twinkleproddelete.currentdeletor = window.setInterval( toCall, 1000, work ); } twinkleproddelete.callbacks = { main: function( self ) { var xmlDoc = self.responseXML; var normal = xmlDoc.evaluate( '//normalized/n/@to', xmlDoc, null, XPathResult.STRING_TYPE, null ).stringValue; if( normal ) { self.params.page = normal; }		var exists = xmlDoc.evaluate( 'boolean(//pages/page[not(@missing)])', xmlDoc, null, XPathResult.BOOLEAN_TYPE, null ).booleanValue;

if( ! exists ) { self.statelem.error( "It seems that the page doesn't exists, perhaps it has already been deleted" ); return; }

var query = { 'action': 'query', 'list': 'backlinks', 'blfilterredir': 'redirects', 'bltitle': self.params.page, 'bllimit': userIsInGroup( 'sysop' ) ? 5000 : 500 // 500 is max for normal users, 5000 for bots and sysops };		var wikipedia_api = new Wikipedia.api( 'Grabbing redirects', query, twinkleproddelete.callbacks.deleteRedirectsMain ); wikipedia_api.params = self.params; wikipedia_api.post;

var query = { 'title': self.params.page, 'action': 'delete' };		var wikipedia_wiki = new Wikipedia.wiki( 'Deleting page ' + self.params.page, query, twinkleproddelete.callbacks.deletePage, function( self ) { 				--twinkleproddelete.currentDeleteCounter;				var link = document.createElement( 'a' );				link.setAttribute( 'href', 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_wiki.params = self.params;		wikipedia_wiki.followRedirect = false;		wikipedia_wiki.get;			},	deleteRedirectsMain: function( self ) {		var xmlDoc = self.responseXML;		var snapshot = xmlDoc.evaluate('//backlinks/bl/@title', xmlDoc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );

var total = snapshot.snapshotLength * 2;

if( snapshot.snapshotLength == 0 ) { return; }

var statusIndicator = new Status('Deleting redirects', '0%');

var onsuccess = function( self ) { var obj = self.params.obj; var total = self.params.total; var now = parseInt( 100 * ++(self.params.current)/total ) + '%'; obj.update( now ); self.statelem.unlink; if( self.params.current >= total ) { obj.info( now + ' (completed)' ); Wikipedia.removeCheckpoint; }		}		var onloaded = onsuccess;

var onloading = function( self ) {}

Wikipedia.addCheckpoint; if( snapshot.snapshotLength == 0 ) { statusIndicator.info( '100% (completed)' ); Wikipedia.removeCheckpoint; return; }

var params = clone( self.params ); params.current = 0; params.total = total; params.obj = statusIndicator;

for ( var i = 0; i < snapshot.snapshotLength; ++i ) { var title = snapshot.snapshotItem(i).value; var query = { 'title': title, 'action': 'delete' }			var wikipedia_wiki = new Wikipedia.wiki( "Deleting " + title, query, twinkleproddelete.callbacks.deleteRedirects ); wikipedia_wiki.params = params; wikipedia_wiki.onloading = onloading; wikipedia_wiki.onloaded = onloaded; wikipedia_wiki.onsuccess = onsuccess; wikipedia_wiki.followRedirect = false; wikipedia_wiki.get; }	},	deleteRedirects: function( self ) { var form = this.responseXML.getElementById( 'deleteconfirm' ); if( ! form ) { // Hell, image deletion is b0rked :(			form = this.responseXML.getElementsByTagName( 'form' )[0];			var postData = {				'wpReason': "Speedy deleted per (CSD R1), Redirect to deleted page \"" + self.params.page + "\"." + TwinkleConfig.deletionSummaryAd,				'wpEditToken': form.wpEditToken.value			}		} else {

var postData = { 'wpWatch': form.wpWatch.checked ? '' : undefined, 'wpReason': "Speedy deleted per (CSD R1), Redirect to deleted page \"" + self.params.page + "\"." + TwinkleConfig.deletionSummaryAd, 'wpEditToken': form.wpEditToken.value }		}		self.post( postData ); },	deletePage: function( self ) { var form = this.responseXML.getElementById( 'deleteconfirm' ); var postData = { 'wpWatch': form.wpWatch.checked ? '' : undefined, 'wpReason': "Deleted because expired \[\[WP:PROD\]\]; Reason given: " + self.params.reason + "." + TwinkleConfig.deletionSummaryAd, 'wpEditToken': form.wpEditToken.value }		self.post( postData ); } }

title: User:Flewis/twinkledeprod.js