User:Equazcion/csdhelper.js

/* ============================================== *\ \* ============================================== */
 * CSD Helper - JavaScript CSD Script
 * for Wikipedia
 * Created by Alex Barley User:Ale_jrb
 * Tracker: User:Ale_jrb/Scripts
 * You are advised to import this script to your
 * monobook.js page - AVOID CREATING YOUR OWN
 * VERSION WHERE POSSIBLE.
 * Instructions for this script can be found at
 * User:Ale_jrb/Scripts - refer to this for
 * setting details.
 * Instructions for this script can be found at
 * User:Ale_jrb/Scripts - refer to this for
 * setting details.

// NB. this script relies on User:Ale_jrb/Scripts/waLib.js. // the following settings are used in this script: if (notifyByDefaultDec == null) 	var notifyByDefaultDec	= true;			// whether to check the 'notify tagger' box by default when declining a speedy deletion request if (notifyByDefaultDel == null) 	var notifyByDefaultDel	= false;		// whether to check the 'notify tagger' box by default when changing a speedy deletion rationale if (notifyByDefaultPrd == null) 	var notifyByDefaultPrd	= true;			// whether to check the 'notify tagger' box by default when converting a speedy deletion to PROD if (notifyByDefaultNew == null) 	var notifyByDefaultNew	= true;			// whether to check the 'use newbie message' box by default if (notifyLimit == null) 			var notifyLimit			= 12;			// how many revisions should be retrieved when determining who tagged the page if ( notifyTemplate == null )		var notifyTemplate		= 'User:Ale_jrb/Scripts/CSDHelper'; // the template that should be substituted for notification messages

if (redirectAfterDel == null) 		var redirectAfterDel	= mw.config.get ( 'wgScript' ) + '?title=Category:Candidates_for_speedy_deletion&action=purge#Pages_in_category'; // where to redirect after deletion if (myDeleteReasons == null)		var myDeleteReasons		= new Array; 	// any addition speedy deletion reasons to add to the list

if (logOnDecline == null)			var logOnDecline		= false; if (logOnDeclinePath == null)		var logOnDeclinePath	= ''; if (overwriteDeclineReasons == null)var overwriteDeclineReasons	= false; 		// whether to overwrite the in-build decline reasons with the user defined ones if (overwriteDeleteReasons == null)var overwriteDeleteReasons	= false; 		// whether to overwrite the in-build delete reasons with the user defined ones if (myDeclineReasons == null)		var myDeclineReasons		= new Array; 	// any addition speedy deletion decline reasons to add to the list if (myDeclineListing == null)		var myDeclineListing		= '%CRITERION%: %REASON%' // the appearance of the option in the drop-down box if (myDeclineSummary == null)		var myDeclineSummary		= 'Speedy deletion %ACTION%. Criterion %CRITERION% does not apply: %REASON%';	// the summary to use when removing a deletion tag from a page because it has been declined or contested if (myDeclineSummarySpecial == null)var myDeclineSummarySpecial	= 'Speedy deletion %ACTION%. %REASON%';	// the summary to use when removing a deletion tag from a page IN A SEPCIAL CASE. NOTE: %CRITERION% will be blank!

/* ============================================== *\ \* ============================================== */
 * WikiApps JavaScript GUI, API & AJAX Library
 * for MediaWiki v1.13 and above
 * Created (c) by Alex Barley User:Ale_jrb
 * version 1.0.10m
 * version 1.0.10m

// mediawiki objects function wa_mediawikiUser ( who ) { if ( ! who ) return false; var waUserObj			= this; this.rootApi			= wgScriptPath + '/api.php'; this.getUserGroup = function(group, onDone) { if (who == 'self') { for (var i = 0; i < wgUserGroups.length; i ++) { if (wgUserGroups[i] == group) return true; }			return false; } else { this.ajax 				= new wa_ajaxcall; this.ajax.requestUrl 	= this.rootApi + '?format=xml&action=query&list=users&usprop=groups&ususers=' + encodeURIComponent(who); this.ajax.doRequest		(function { 										wa_mediawikiUser.apiResponse = waUserObj.ajax.response;										waUserGroups = wa_mediawikiUser.apiResponse.getElementsByTagName('g');										for (var i = 0; i < waUserGroups.length; i ++) {											if (waUserGroups[i].childNodes[0].nodeValue == group) { onDone(true); return true; }										}										onDone(false);									}); }	}	this.getUserContribs = function ( number, onDone ) { if (who == 'self') 		{ var user = wgUserName; } else { var user = who; } if (number == 0) 		number = 1; if (number > 100) 		number = 100; this.ajax 				= new wa_ajaxcall; this.ajax.requestUrl 	= this.rootApi + '?format=xml&action=query&list=usercontribs&uclimit=' + number + '&ucuser=' + encodeURIComponent(who) + '&ucprop=ids|title|timestamp|comment'; this.ajax.doRequest		(function { 									wa_mediawikiUser.apiResponse = waUserObj.ajax.response; 									waUserObj.editDetails = [];									if (wa_mediawikiUser.apiResponse.getElementsByTagName('item').length == 0) {										waUserObj.editDetails[0] = new Object;										waUserObj.editDetails[0]['pageid'] 		= false; waUserObj.editDetails[0]['revid'] 		= false;										waUserObj.editDetails[0]['title'] 		= false; waUserObj.editDetails[0]['timestamp'] 	= false;									}									for (var i = 0; i < wa_mediawikiUser.apiResponse.getElementsByTagName('item').length; i ++) { // for each revision										var tempData = wa_mediawikiUser.apiResponse.getElementsByTagName('item')[i];										waUserObj.editDetails[i] = new Object;										waUserObj.editDetails[i]['pageid'] 		= tempData.getAttribute('pageid');										waUserObj.editDetails[i]['revid'] 		= tempData.getAttribute('revid'); waUserObj.editDetails[i]['title'] 		= tempData.getAttribute('title'); waUserObj.editDetails[i]['timestamp'] 	= tempData.getAttribute('timestamp'); }									onDone; });	}	this.getUserLogs = function(number, onDone) {		if (who == 'self') 		{ var user = wgUserName; } else { var user = who; }		if (number == 0) 		number = 1;		if (number > 100) 		number = 100;		this.ajax 				= new wa_ajaxcall;		this.ajax.requestUrl 	= this.rootApi + '?format=xml&action=query&list=logevents&lelimit=' + number + '&leuser=' + encodeURIComponent(who) + '&leprop=ids|title|timestamp|comment|type';		this.ajax.doRequest		(function { wa_mediawikiUser.apiResponse = waUserObj.ajax.response; waUserObj.logDetails = []; if (wa_mediawikiUser.apiResponse.getElementsByTagName('item').length == 0) { waUserObj.logDetails[0] = new Object; waUserObj.logDetails[0]['pageid'] 		= false; waUserObj.logDetails[0]['logid'] 		= false; waUserObj.logDetails[0]['title'] 		= false; waUserObj.logDetails[0]['timestamp'] 	= false; waUserObj.logDetails[0]['type'] 		= false; waUserObj.logDetails[0]['action'] 		= false; }									for (var i = 0; i < wa_mediawikiUser.apiResponse.getElementsByTagName('item').length; i ++) { // for each revision var tempData = wa_mediawikiUser.apiResponse.getElementsByTagName('item')[i]; waUserObj.logDetails[i] = new Object; waUserObj.logDetails[i]['pageid'] 		= tempData.getAttribute('pageid'); waUserObj.logDetails[i]['logid'] 		= tempData.getAttribute('logid'); waUserObj.logDetails[i]['title'] 		= tempData.getAttribute('title'); waUserObj.logDetails[i]['timestamp'] 	= tempData.getAttribute('timestamp'); waUserObj.logDetails[i]['type'] 		= tempData.getAttribute('type'); waUserObj.logDetails[i]['action'] 		= tempData.getAttribute('action'); }									onDone; });	}	// construct	if (who == 'self') {		this.isSysop = this.getUserGroup('sysop');		this.isRollback = this.getUserGroup('rollback');		this.isAutoconfirmed = this.getUserGroup('autoconfirmed');	} } var waUser = new wa_mediawikiUser('self');

function wa_mediawikiApi { // this function handles a multitude of Wiki API calls. var wa_mediaWiki		= this;	// callback this.rootApi			= wgScriptPath + '/api.php'; this.apiResponse		= false; 			// actual response from API - allows manual parsing, if desired this.apiPage			= new Object; this.apiPage['plain']	= false; 			// the provided name of the last page called in this object this.apiPage['enc']		= false; 			// the encoded name of the last page called in this object this.data				= new Object; 		// general response of the method called - associative array filled with requested data this.ajax				= false; 			// the ajax object - allows manual access to the ajax object/functions, if desired this.onCompleteAction 	= function { return true; } 	// onCompleteAction is the function that will be called whenever the current operation is complete this.internalOnComplete	= function { return true; } 	// internalOnComplete is the function that will be called (callback) when an internal operation completes this.internalRequest	= false;						// internalRequest specifies whether this is an internal callback or not this.getToken = function(token, page) { // set vars this.apiPage['plain'] 		= page; if (page.indexOf('%20') > -1) { this.apiPage['enc'] = page; } else { this.apiPage['enc'] = encodeURIComponent(page); } page 						= this.apiPage['enc']; token 						= token.toLowerCase; // verification if (token.match(/(edit|delete|protect|move|block|unblock|rollback)/i) == null) return false; // check rollback if (token.match(/rollback/i) != null) { this.getPage(page, 1, 'rollback-int'); return true; }		// go		var requestUrl 			= this.rootApi + '?action=query&format=xml&prop=info&inprop=talkid&intoken=' + token + '&titles=' + page; this.ajax 				= new wa_ajaxcall; this.ajax.requestUrl 	= requestUrl; this.ajax.doRequest		(function { 									var internal = [];									wa_mediaWiki.apiResponse 			= wa_mediaWiki.ajax.response; 									wa_mediaWiki.data['token']			= [];									wa_mediaWiki.data['token'].push		(wa_mediaWiki.apiPage['enc'], encodeURIComponent(wa_mediaWiki.apiResponse.getElementsByTagName('page')[0].getAttribute(token+'token')));									if (wa_mediaWiki.apiResponse.getElementsByTagName('page')[0].getAttribute('missing') != null) { internal[0] = true; } else { internal[0] = false; }									if (wa_mediaWiki.apiResponse.getElementsByTagName('page')[0].getAttribute('talkid') != null) { 										internal[1] = wa_mediaWiki.apiResponse.getElementsByTagName('page')[0].getAttribute('talkid'); } else { internal[1] = false; }									if (wa_mediaWiki.internalRequest == false) {wa_mediaWiki.onCompleteAction(wa_mediaWiki.data); } else 										{ wa_mediaWiki.internalRequest = false; wa_mediaWiki.internalOnComplete(wa_mediaWiki.data, internal); } });		return true;	}	this.getPage = function(page, revisions, properties) {		// set vars		if (properties == 'rollback-int') {			properties = 'rollback';		} else {			this.apiPage['plain'] 	= page;			if (page.indexOf('%20') > -1) { this.apiPage['enc'] = page; } else { this.apiPage['enc'] = encodeURIComponent(page); }			page 					= this.apiPage['enc'];		}		// verification		if (revisions > 500) revisions = 500;		if (properties.match(/^(?:(?:ids|flag|timestamp|user|size|comment|content|rollback)\|?)*$/i) == null) properties = 'ids|user|content';		// go		if (properties.match(/rollback/i) != null) {			var rollbackRequest 	= true;			properties = properties.replace(/\|rollback\|/ig, );			properties = properties.replace(/rollback\|/ig, );			properties = properties.replace(/\|rollback/ig, );			properties = properties.replace(/\|\|/ig, '|');			properties = properties.replace(/rollback/ig, ); var requestUrl 			= this.rootApi + '?action=query&format=xml&prop=revisions&titles=' + page + '&rvtoken=rollback&rvprop=' + properties + '&rvlimit=' + revisions; } else { var rollbackRequest 	= false; var requestUrl 			= this.rootApi + '?action=query&format=xml&prop=revisions&titles=' + page + '&rvprop=' + properties + '&rvlimit=' + revisions; }		this.ajax 				= new wa_ajaxcall; this.ajax.requestUrl 	= requestUrl; this.ajax.doRequest		(function { 									wa_mediaWiki.apiResponse 			= wa_mediaWiki.ajax.response; 									wa_mediaWiki.data					= new Object;									if (wa_mediaWiki.apiResponse.getElementsByTagName('rev')[0] == null) { wa_mediaWiki.data['page'] = new Object; wa_mediaWiki.data['page']['status'] = 'E'; } else {										wa_mediaWiki.data['page'] 				= new Object; 										wa_mediaWiki.data['page']['revisions']	= [];										wa_mediaWiki.data['page']['status'] 	= 'OK';										for (var i = 0; i < wa_mediaWiki.apiResponse.getElementsByTagName('rev').length; i ++) { // for each revision											wa_mediaWiki.data['page']['revisions'][i] = new Object;											// get details											if (properties.match(/ids/i) != null) wa_mediaWiki.data['page']['revisions'][i]['id'] 																		= wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('revid');											if (properties.match(/size/i) != null) wa_mediaWiki.data['page']['revisions'][i]['size'] = wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('size'); if (properties.match(/user/i) != null) wa_mediaWiki.data['page']['revisions'][i]['user'] = wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('user'); if (properties.match(/comment/i) != null) wa_mediaWiki.data['page']['revisions'][i]['comment'] = wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('comment'); if (properties.match(/timestamp/i) != null) wa_mediaWiki.data['page']['revisions'][i]['timestamp'] = wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('timestamp'); if ( (rollbackRequest == true) && (i == 0) ) { wa_mediaWiki.data['token']		= []; wa_mediaWiki.data['token'][1] 	= encodeURIComponent(wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].getAttribute('rollbacktoken')); var internal = []; if (wa_mediaWiki.apiResponse.getElementsByTagName('page')[0].getAttribute('missing') != null) { internal[0] = true; } else { internal[0] = false; } }											// get content if (properties.match(/content/i) != null) { wa_mediaWiki.data['page']['revisions'][i]['content'] = ''; for (var j = 0; j < wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].childNodes.length; j ++) { wa_mediaWiki.data['page']['revisions'][i]['content'] += wa_mediaWiki.apiResponse.getElementsByTagName('rev')[i].childNodes[j].nodeValue; }											}										}									}									if (wa_mediaWiki.internalRequest == false) {wa_mediaWiki.onCompleteAction(wa_mediaWiki.data); } else { if (typeof internal == 'undefined') { var internal = false; } wa_mediaWiki.internalRequest = false; wa_mediaWiki.internalOnComplete(wa_mediaWiki.data, internal); } });		return true;	}	this.getLastNotUser = function(page, excludeWho) {		// this function gets the username of the most recent editor to the page who ISN'T excludeWho		if (typeof excludeWho != 'string') return false;		this.apiPage['plain'] 	= page;		if (page.indexOf('%20') > -1) { this.apiPage['enc'] = page; } else { this.apiPage['enc'] = encodeURIComponent(page); }		page 					= this.apiPage['enc'];		var requestUrl 			= this.rootApi + '?action=query&format=xml&prop=revisions&titles=' + page + '&rvprop=user&rvlimit=1&rvexcludeuser=' + encodeURIComponent(excludeWho);		this.ajax 				= new wa_ajaxcall;		this.ajax.requestUrl 	= requestUrl;		this.ajax.doRequest		(function { var ret; wa_mediaWiki.apiResponse 			= wa_mediaWiki.ajax.response; if (wa_mediaWiki.apiResponse.getElementsByTagName('rev')[0] == null) { // an error occurred - sort it										if (wa_mediaWiki.apiResponse.getElementsByTagName('rev')[0].getAttribute('missing') != null) { ret = 'missing'; } else { ret = 'no-other-user'; } } else { ret = wa_mediaWiki.apiResponse.getElementsByTagName('rev')[0].getAttribute('user'); }									wa_mediaWiki.onCompleteAction(ret); });		return true;	}	this.editPage = function(title, text, summary, minor, addWhere, token) {		// shortcut to performAction('edit')		var details = [];		details[0]	= text;		details[1]	= summary;		details[2]	= minor;		details[3]	= addWhere;		wa_mediaWiki.performAction('edit', title, details, token);		return true;	}	this.deletePage = function(title, reason, token) {		// shortcut to performAction('delete')		var details = reason;		wa_mediaWiki.performAction('delete', title, details, token);		return true;	}	this.rollbackPage = function(title, user, summary, token) {		// shortcut to performAction('rollback')		// NB. a user must be provided; rollback will only occur if they are the last editor to the page.		var details = [];		details[0] 	= user;		if (summary !== false) { details[1] = summary; } else { details[1] = ''; }		wa_mediaWiki.performAction('rollback', title, details, token);	}	this.performAction = function(action, target, details, token, internal) { // this module only accepts block, edit, rollback and deletion requests. Other actions must be performed manually, though the getToken method allows the // easy retrieval of the correct token for almost any action. // --		// NB. internal is an internal parameter, allowing library to communicate internal data between functions. Modifying it will result in unexpected actions. // verification if ( (token == null) || (token == '') || (token == 0) || (token == false) ) { // get a token this.internalRequest = true; this.internalOnComplete = function(passToken, internal) { wa_mediaWiki.performAction(action, target, details, passToken['token'][1], internal); }; this.getToken(action, target); return false; }		// set vars this.apiPage['plain'] 			= target; if (target.indexOf('%20') > -1) { this.apiPage['enc'] = target; } else { this.apiPage['enc'] = encodeURIComponent(target); } target 							= this.apiPage['enc']; if (details == null) 			{ details = ''; } else if (typeof(details) == 'object') { for (x in details) { if (typeof details[x] == 'string') details[x] = encodeURIComponent(details[x]); } } else { details = encodeURIComponent(details); } // go		switch ( action ) { case 'edit': // shortcut to this method from editPage method if (typeof(details) != 'object') 		return false; 		// we need an array: if (typeof(details[0]) != 'string') 	details[0] = '';	//details[0] - text if (typeof(details[1]) != 'string') 	details[1] = '';	//details[1] - edit summary if (typeof(details[2]) != 'boolean') 	details[2] = false;	//details[2] - minor edit? if (typeof(details[3]) != 'string') 	details[3] = 'text';//details[3] - appendtext, prependtext, text if (details[2] == true) { var minor = 'minor=true'; } else { var minor = 'notminor=true'; } if (internal[0] == true) details[3] = 'text'; if (details[3] == 'appendtext') { details[0] = encodeURIComponent('\n\n') + details[0]; } this.ajax					= new wa_ajaxcall; this.ajax.requestUrl		= this.rootApi; this.ajax.postParams		= 'format=xml&action=edit&title=' + target + '&summary=' + details[1] + '&' + details[3] + '=' + details[0] + '&' + minor + '&token=' + token; this.ajax.post				(function {												wa_mediaWiki.apiResponse = wa_mediaWiki.ajax.response;												wa_mediaWiki.onCompleteAction;												return true;											}); break; case 'rollback': if ( internal[0] == true ) { wa_mediaWiki.onCompleteAction(false); return false; } if ( (details[1] == '') || (details[1] == null) || (typeof details[1] == 'undefined') ) { var useCustomSummary = false; } else { var useCustomSummary = true; } var params = 'format=xml&action=rollback&title=' + target + '&user=' + details[0] + '&token=' + token; if (useCustomSummary == true) params += '&summary=' + details[1]; this.ajax					= new wa_ajaxcall; this.ajax.requestUrl		= this.rootApi; this.ajax.postParams		= params; this.ajax.post				(function {												wa_mediaWiki.apiResponse = wa_mediaWiki.ajax.response;												if ( (wa_mediaWiki.apiResponse.getElementsByTagName('error')[0] == null) || (wa_mediaWiki.apiResponse.getElementsByTagName('error')[0].getAttribute('code') == null) )													{ 														//if (wa_mediaWiki.apiResponse.getElementsByTagName('rollback')[0].getAttribute('revid') == wa_mediaWiki.apiResponse.getElementsByTagName('rollback')[0].getAttribute('old_revid')) {														//	var r = false;														//} else {															var r = wa_mediaWiki.apiResponse.getElementsByTagName('rollback')[0].getAttribute('revid');														//}													} else { var r = false; }												wa_mediaWiki.onCompleteAction(r);												return true;											}); break; case 'delete': // we have the required token. Perform the deletion! if (internal[0] == true) 	return false; this.ajax					= new wa_ajaxcall; this.ajax.requestUrl		= this.rootApi; this.ajax.postParams		= 'format=xml&action=delete&title=' + target + '&reason=' + details + '&token=' + token; this.ajax.post				(function {												wa_mediaWiki.apiResponse = wa_mediaWiki.ajax.response;												wa_mediaWiki.onCompleteAction(internal[1]);												return true;											}); return true; break; case 'block': // additional verification for blocking if (typeof(details) != 'object') 		return false; 		// we need an array: if (typeof(details[0]) != 'string') 	return false;		//details[0] - expiry as string - you must provide this, or the block will not happen if (typeof(details[1]) != 'boolean') 	return false;		//details[1] - anonymous only - you must provide this, or the block will not happen if (typeof(details[2]) != 'string') 	details[2] = '';	//details[2] - reason as string if (typeof(details[3]) != 'boolean') 	details[3] = true;	//details[3] - prevent account creation if (typeof(details[4]) != 'boolean') 	details[4] = true;	//details[4] - autoblock - default, hardblock // build valid syntax if (details[1] == true) { var anonOnly = '&anononly'; } else { var anonOnly = ''; } if (details[3] == true) { var createAccount = '&nocreate'; } else { var createAccount = ''; } if (details[4] == true) { var autoblock = '&autoblock'; } else { var autoblock = ''; } // we have the required token this.ajax					= new wa_ajaxcall; this.ajax.requestUrl		= this.rootApi; this.ajax.postParams		= 'format=xml&action=block&user=' + target + '&expiry=' + details[0] + '&reason=' + details[2] + anonOnly + createAccount + autoblock + '&token=' + token; this.ajax.post				(function {												wa_mediaWiki.apiResponse = wa_mediaWiki.ajax.response;												wa_mediaWiki.onCompleteAction;												return true;											}); break; default: return false; break; }	} }

// non-gui objects function wa_ajaxcall { var waMyAjax = this; this.requestType		= 'GET'; this.responseType		= 'xml'; this.requestUrl			= ''; waMyAjax.pageRequest 	= false; this.postParams			= ''; this.response 			= false; this.abort = function { if ( waMyAjax.pageRequest != false ) { waMyAjax.pageRequest.abort ; return true; }	}	this.post = function ( runOnComplete ) { waMyAjax.requestType = 'POST'; waMyAjax.doRequest ( runOnComplete ); }	this.get = function ( runOnComplete ) { waMyAjax.requestType = 'GET'; waMyAjax.doRequest ( runOnComplete ); }	this.doRequest = function ( runOnComplete ) { if ( this.requestUrl == '' ) return false; if ( window.XMLHttpRequest ) { // if good browser waMyAjax.pageRequest = new XMLHttpRequest ; }		else if ( window.ActiveXObject ) { // if IE			try { // try request 1 waMyAjax.pageRequest = new ActiveXObject ( "Msxml2.XMLHTTP" ); } 			catch ( e ) { // it failed. try {	// try request 2 waMyAjax.pageRequest = new ActiveXObject ( "Microsoft.XMLHTTP" ); }				catch ( e ) { return false; } }		}		else {			return false; }		waMyAjax.pageRequest.onreadystatechange = function { if ( waMyAjax.pageRequest.readyState == 4 ) { if ( waMyAjax.pageRequest.status == 200 ) { if ( waMyAjax.responseType == 'xml' ) { waMyAjax.response = waMyAjax.pageRequest.responseXML; } else { waMyAjax.response = waMyAjax.pageRequest.responseText; }					if ( waMyAjax.pageRequest.responseXML ) waMyAjax.responseXML = waMyAjax.pageRequest.responseXML; if ( waMyAjax.pageRequest.responseText ) waMyAjax.responseText = waMyAjax.pageRequest.responseText; runOnComplete ; }			}		}		if ( this.requestType == 'GET' ) { // do get request waMyAjax.pageRequest.open('GET', this.requestUrl, true); switch (this.responseType) { default: case 'xml': if ( waMyAjax.pageRequest.overrideMimeType ) { waMyAjax.pageRequest.overrideMimeType ( 'text/xml' ); } else { waMyAjax.pageRequest.setRequestHeader ( 'Content-type', 'text/xml' ); } break; case 'html': if ( waMyAjax.pageRequest.overrideMimeType ) waMyAjax.pageRequest.overrideMimeType ( 'text/html' ); break; }			waMyAjax.pageRequest.send ( null ); }		else if ( this.requestType == 'POST' ) {			// do post request waMyAjax.pageRequest.open ( 'POST', this.requestUrl, true ); waMyAjax.pageRequest.setRequestHeader ( "Content-type", "application/x-www-form-urlencoded" ); waMyAjax.pageRequest.setRequestHeader ( "Content-length", this.postParams.length ); waMyAjax.pageRequest.setRequestHeader ( "Connection", "close" ); waMyAjax.pageRequest.send ( this.postParams ); }		else { /* unrecognised */ } };	return true; }

// drawing objects function wa_document { // document -- main interface representation. grabs required document ids for easy use. not used directly. sits above wiki interface, to allow override // vars this.wk_base 				= document.getElementsByTagName('body')[0]; this.wk_content_base 		= document.getElementById('bodyContent'); this.wk_top_links_port		= document.getElementById('p-personal'); this.wk_top_links			= document.getElementById('pt-userpage').parentNode; this.wk_pref_link			= document.getElementById('pt-preferences'); this.root					= wgArticlePath; this.user					= wgUserName; this.page					= wgTitle; return true; }

function wa_window ( parent_opt ) { // window -- main interface compontent. wikiapps gui is built of windows. they're esentially divs, attached to a parent div. child of document. // providing a parent_opt object (must be another window) will result in that object being the parent node. otherwise, the default document // object is used. // vars - enable quick window creation by setting CSS style defaults this.win_fill 		= false; 			this.win_bd_wd 		= 0; this.win_top 		= 0; 				this.win_bd_rt		= ''; this.win_left 		= 0; 				this.win_bd_lf		= ''; this.win_width 		= 0; 				this.win_bd_bt		= ''; this.win_height 	= 0; 				this.win_bd_tp		= ''; this.win_bg 		= '#000000'; 		this.win_class 		= ''; this.win_bd 		= '#000000'; 		this.win_alpha 		= 1; this.win_disp		= 'block';			this.win_obj 		= document.createElement ( 'div' ); this.win_z			= '9999999'; this.win_pos		= 'absolute';		this.win_handler	= 'click'; this.win_func		= function { };	this.win_fade		= 'visible'; this.win_attached	= false;			this.win_cursor		= 'auto'; this.win_padding	= 3;				this.win_content	= ''; this.win_margin		= 0;				this.win_id 		= ''; this.win_talign		= 'left';			this.win_overflow	= 'visible'; this.win_right		= false;			this.win_bottom		= false; this.win_maintfill	= true;				this.hidden			= false; this.win_fontsize	= 10; if ( parent_opt == null ) { this.parentObj = this.wk_base; } else { if ( typeof parent_opt.win_obj !== 'undefined' ) { this.parentObj = parent_opt.win_obj; } else if ( parent_opt != null ) { this.parentObj = parent_opt; }	}	// methods this.applyAll = function { // applyAll - method // applyAll applies current settings to the window object. if createNew is set as true, a new window will be created and appended to the base. // if not provided, the current object's settings will be updated. special behaviour: setting win_fill to true will cause the window to // automatically maintain the shape of the window. setting it to false will disable auto updating, and unfill the screen. this.win_obj.style.position 						= this.win_pos; this.win_obj.style.zIndex 							= this.win_z; // special behaviour - fill screen, usage background cover etc. only 1 per page if (this.win_fill == true) { this.win_obj.style.position						= 'fixed'; this.win_obj.style.top							= '0px'; this.win_obj.style.left							= '0px'; this.win_obj.style.width						= document.documentElement.clientWidth + 'px'; this.win_obj.style.height						= document.documentElement.clientHeight + 'px'; // fill screen - attach updater to window resize var wa_selfFill		= this; if (this.win_maintfill == true) { if (window.addEventListener) { window.addEventListener('resize', function { 						wa_selfFill.applyAll;					}, false); }				else {					window.attachEvent('onresize', function { 						wa_selfFill.applyAll;					}); }			}		}		else {			if (this.win_right !== false) { this.win_obj.style.right = this.win_right + 'px'; } else { this.win_obj.style.left = this.win_left + 'px'; } if (this.win_bottom !== false) { this.win_obj.style.bottom = this.win_bottom + 'px'; } else { this.win_obj.style.top = this.win_top + 'px'; } if (this.win_width != 0) { this.win_obj.style.width	 = this.win_width 	+ 'px'; } else { this.win_obj.style.width 	= 'auto'; } if (this.win_height != 0) { this.win_obj.style.height= this.win_height 	+ 'px'; } else { this.win_obj.style.height 	= 'auto'; } }		if (this.win_obj.addEventListener) 					{ this.win_obj.addEventListener(this.win_handler, this.win_func, false); } else { this.win_obj.attachEvent('on'+this.win_handler, this.win_func); } this.win_obj.style.backgroundColor					= this.win_bg; this.win_obj.style.padding							= this.win_padding	+ 'px'; if (this.win_margin != 'auto') { this.win_obj.style.margin = this.win_margin + 'px'; } else { this.win_obj.style.margin = 'auto'; } this.win_obj.style.border							= this.win_bd_wd 	+ 'px solid ' + this.win_bd; if (this.win_bd_rt != '') this.win_obj.style.borderRight 	= this.win_bd_rt; if (this.win_bd_tp != '') this.win_obj.style.borderTop 		= this.win_bd_tp; if (this.win_bd_bt != '') this.win_obj.style.borderBottom 	= this.win_bd_bt; if (this.win_bd_lf != '') this.win_obj.style.borderLeft 	= this.win_bd_lf; this.win_obj.style.cursor							= this.win_cursor; this.win_obj.style.overflow							= this.win_overflow; this.win_obj.style.opacity							= this.win_alpha.toString; this.win_obj.style.MozOpacity						= this.win_alpha.toString; this.win_obj.style.filter							= 'alpha(opacity='+ (this.win_alpha * 100) +')'; this.win_obj.style.textAlign						= this.win_talign; this.win_obj.style.fontSize							= this.win_fontsize	+ 'px'; // compatibility with 'hide' module if (this.hidden == false) this.win_obj.style.display = this.win_disp; this.win_obj.innerHTML 								= this.win_content; if (this.win_attached == false) { this.parentObj.appendChild(this.win_obj); this.win_attached = true; } return true; // successful init };	// special methods - effects for windows this.center = function(centerPositions, maintainCenter, offset) { // center - places the window in the centre of the user's screen. set maintainCenter to true and this position will be kept even if // the window is resized. if (((this.win_pos != 'fixed') && (this.win_pos != 'absolute')) || (this.win_fill == true)) { return false; } var screenWidth 			= document.documentElement.clientWidth; var screenHeight 			= document.documentElement.clientHeight; var myWidth 				= this.win_obj.offsetWidth; var myHeight 				= this.win_obj.offsetHeight; var leftPos					= ((screenWidth / 2) - (myWidth / 2)); var topPos					= ((screenHeight / 2) - (myHeight / 2)); if (typeof offset == 'object') { leftPos += offset[0]; topPos	+= offset[1]; }		if ((centerPositions == 'left') || (centerPositions == 'both')) this.win_obj.style.left = leftPos + 'px'; if ((centerPositions == 'top') || (centerPositions == 'both')) this.win_obj.style.top 	= topPos + 'px'; if (maintainCenter == true) { var wa_selfCenter = this; if (window.addEventListener) { window.addEventListener('resize', function { 					wa_selfCenter.center(centerPositions);				}, false); }			else {				window.attachEvent('onresize', function { 					wa_selfCenter.center(centerPositions);				}); }		}		return true; };	this.fade = function(fadeSpeed, opacityLimit, runWhenFinished) { // fade - toggle method - the object will be faded in if currently hidden, and faded out if currently visible. var stepDefault	= 20; var stepNumber	= fadeSpeed * stepDefault; var stepSize	= 1 / stepNumber; var wa_selfFade = this; if (opacityLimit == null) opacityLimit = 0; if (interval != null) clearInterval(interval); // user call - prepare fade if (this.win_fade == 'visible') { // start fade out var tempAlpha = 1; // just in case wa_selfFade.win_alpha					= tempAlpha; wa_selfFade.win_obj.style.opacity 		= tempAlpha; wa_selfFade.win_obj.style.MozOpacity	= tempAlpha; wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')'; var interval = setInterval(function {				tempAlpha = parseFloat(wa_selfFade.win_obj.style.opacity);				tempAlpha = tempAlpha - stepSize;				wa_selfFade.win_alpha					= tempAlpha;				wa_selfFade.win_obj.style.opacity 		= tempAlpha;				wa_selfFade.win_obj.style.MozOpacity	= tempAlpha;				wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')';				if (tempAlpha <= (0 + opacityLimit)) {					tempAlpha = (0 + opacityLimit);					wa_selfFade.win_alpha					= tempAlpha;					wa_selfFade.win_obj.style.opacity 		= tempAlpha;					wa_selfFade.win_obj.style.MozOpacity	= tempAlpha;					wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')';					wa_selfFade.win_obj.style.display	= 'none';					wa_selfFade.win_fade				= 'invisible';					if (runWhenFinished != null) runWhenFinished;					clearInterval				(interval);				}			}, (1000 / stepDefault)); }		else {			// start fade in			var tempAlpha = 0; // just in case wa_selfFade.win_alpha					= tempAlpha; wa_selfFade.win_obj.style.opacity 		= tempAlpha; wa_selfFade.win_obj.style.MozOpacity	= tempAlpha; wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')'; this.win_obj.style.display	= 'block'; var interval = setInterval(function {				tempAlpha = parseFloat(wa_selfFade.win_obj.style.opacity);				tempAlpha = tempAlpha + stepSize;				wa_selfFade.win_alpha					= tempAlpha;				wa_selfFade.win_obj.style.opacity 		= tempAlpha;				wa_selfFade.win_obj.style.MozOpacity	= tempAlpha;				wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')';				if (tempAlpha >= (1 - opacityLimit)) {					tempAlpha = (1 - opacityLimit);					wa_selfFade.win_alpha					= tempAlpha;					wa_selfFade.win_obj.style.opacity 		= tempAlpha;					wa_selfFade.win_obj.style.MozOpacity	= tempAlpha;					wa_selfFade.win_obj.style.filter		= 'alpha(opacity='+ (tempAlpha * 100) +')';					wa_selfFade.win_fade				= 'visible';					if (runWhenFinished != null) runWhenFinished;					clearInterval				(interval);				}			}, (1000 / stepDefault)); }		return true; };	this.setLocation = function( toLeft, toTop, domMove ) { // this is a shortcut for setting the position of a window if ( ! domMove ) { this.win_top = toTop; this.win_left = toLeft; this.applyAll; } else { this.win_obj.style.left = toLeft + 'px'; this.win_obj.style.top = toTop + 'px'; }		return true; };	this.move = function(toTop, toLeft, time, runWhenFinished) { // time is the length of time for the move. To be smooth, the move needs about a frame per 5 pixels of movement, regardless of time. if (runWhenFinished == null) runWhenFinished = function { }; if ( (toTop == this.win_top) && (toLeft == this.win_left) ) return false; // first, calculate the distance to be travelled on both sides var topDis = toTop - this.win_top; var leftDis = toLeft - this.win_left; // pick the bigger one if (Math.abs(topDis) >= Math.abs(leftDis)) { var moveDis = Math.abs(topDis); } else { var moveDis = Math.abs(leftDis); } // divide by the time to get how many pixels we have to move per second var pps = moveDis / time; var smoothSteps = ((1 / time) * 4); var fps = pps / smoothSteps; // we know the number of frames per second. Now, we need to know how far to move in each direction per step. Multiply the fps by the time, // to get the total steps then divide the total distance by the total steps to get a value. var totalSteps = fps * time; if (topDis > 0) { var topMove = smoothSteps; } else if (topDis < 0) { var topMove = (smoothSteps * -1); } else { var topMove = 0; } if (leftDis > 0) { var leftMove = smoothSteps; } else if (leftDis < 0) { var leftMove = (smoothSteps * -1); } else { var leftMove = 0; } var wa_selfMove = this; var i = 0; var interval = setInterval(function {			var newTop = wa_selfMove.win_top + topMove;			var newLeft = wa_selfMove.win_left + leftMove;			wa_selfMove.setLocation(newTop, newLeft);			if (i >= totalSteps) { wa_selfMove.setLocation(toTop, toLeft); clearInterval(interval); runWhenFinished; }			i ++;		}, (1000 / fps)); };	this.hide = function { this.hidden = true; this.win_obj.style.display = 'none'; return true; };	this.show = function { this.hidden = false; this.win_obj.style.display = 'block'; return true; };	this.addScriptEvent = function(eventHandler, eventFunction) { if (this.win_obj.addEventListener) { this.win_obj.addEventListener(eventHandler, eventFunction, false); } 		else { 			this.win_obj.attachEvent('on' + eventHandler, eventFunction); }	};	return true; }

function wa_element(elementType) { // element -- wa building block. elements can be of any type, but if a div, use of wa_window is recommended. element offers a greater level of control, but less automation than // 				windows. elementType must be a valid html element. if (elementType == null) return false; this.ele_obj = document.createElement(elementType); this.attach = function(attachTo, attachWhere) { // attachWhere can be [append, before]. if blank, append is used. if (attachTo == null) return false; if (attachWhere == null) var attachWhere = 'append'; switch (attachWhere) { case 'after': attachTo.parentNode.appendChild(this.ele_obj); break; case 'before': attachTo.parentNode.insertBefore(this.ele_obj, attachTo); break; default: return false; break; }		return true; };	this.addScriptEvent = function(eventHandler, eventFunction) { if (this.ele_obj.addEventListener) { this.ele_obj.addEventListener(eventHandler, eventFunction, false); } 		else { 			this.ele_obj.attachEvent('on' + eventHandler, eventFunction); }	};	this.destroy = function { var selfElement = this.ele_obj; selfElement.parentNode.removeChild(selfElement); selfElement = null; return false; };	return true; }

$(document).ready( function { 	wa_window.prototype = new wa_document;	wa_element.prototype = new wa_document; });

// handy functions // arrays function in_array ( needle, haystack, recursive ) { if ( recursive == true ) { for ( var i in haystack ) { //var i = 0; i < haystack.length; i ++ ) {			if ( ( typeof haystack[i] == 'object' ) && ( typeof haystack[i] != 'function' ) ) {				var t = in_array ( needle, haystack[i], true );				if ( t == true ) return t;			} else {				if ( haystack[i] == needle ) return true;			}		}		return false;	} else {		if ( typeof haystack != 'object' ) return false;		for ( var i = 0; i < haystack.length; i ++ ) {			if ( haystack[i] == needle ) return true;		}		return false;	} }

function sort_array_multi(array, id, direction) { // this function sorts a multi-dimentional array into numerical order based // on an id field in one of the sets. // e.g. [0] = [1, hi] // 		[1] = [3, test] //		[2] = [2, boo] // where [#][0] is the id field would be sorted to [0], [2], [1] is acsending order etc.	if (typeof array != 'object') return false; if ( (direction != 'ascending') && (direction != 'descending') ) { direction = 'descending'; } if (typeof id != 'number') id = 0; var index = []; // the index array is what keeps track of the ids in the array before sorting for (var i = 0; i < array.length; i ++) { index[i] = array[i][id] + '::' + i;	} // first, sort the index array into the correct order. index.sort(function(a,b) { 								var ta = a; var tb = b;								ta = ta.substr(0, ta.indexOf('::'));								tb = tb.substr(0, tb.indexOf('::'));								if (direction == 'ascending') { return (ta - tb); } else { return (tb - ta); }							}); // the index array is now in the right order. build a new array with full content based off the order in the index array. var newArray = []; for (var i = 0; i < index.length; i ++) { var aid = index[i].substr(index[i].indexOf('::') + 2); newArray[i] = array[aid]; }	return newArray; }

function echo_nodes_recursive ( parent ) { var nex = ''; if ( ! parent.childNodes ) { if (parent.nodeValue) if (parent.nodeValue != '') return parent.nodeValue; return false; } else if (parent.childNodes.length == 0) { if (parent.nodeValue) if (parent.nodeValue != '') return parent.nodeValue; return false; }	for (var i = 0; i < parent.childNodes.length; i ++) { var nex2 = echo_nodes_recursive(parent.childNodes[i]); if (nex2 != false) nex = nex + nex2; }	return nex; }

// internet explorer function ie_create_document { if (typeof ActiveXObject == 'undefined') return false; var implementations = ['Microsoft.XMLDOM', 'Msxml2.DOMDocument.3.0', 'MSXML2.DOMDocument', 'MSXML.DOMDocument']; for (var ii in implementations) { try { var r = new ActiveXObject(implementations[ii]); return r;		} catch (e) {} }	return false; }

function ie_getElementById(parent, id) { // parent should be document or an AJAX return etc.	if (parent.childNodes.length == 0) return false; for (var i = 0; i < parent.childNodes.length; i ++) { if (parent.childNodes[i].nodeType == 1){ var at = parent.childNodes[i].attributes; at = at.getNamedItem('id'); if (at != null) if (at.value == id) return parent.childNodes[i]; }

var t = ie_getElementById(parent.childNodes[i], id); if (typeof t == 'object') return t;	} return false; }

function ie_cloneNode(node, cloned) { // clone a node to avoid the stupid IE no such interface error var current; if (!cloned) { current = document.createElement(node.nodeName); } else { current = cloned.appendChild(document.createElement(node.nodeName)); }	for (var j = 0; j < node.attributes.length; j++) { current.setAttribute(node.attributes[j].nodeName, node.attributes[j].nodeValue); }	for (var i = 0; i < node.childNodes.length; i++) { if (node.childNodes[i].nodeType == 1) { ie_cloneNode(node.childNodes[i], current); } else if (node.childNodes[i].nodeType == 3) { var text = document.createTextNode(node.childNodes[i].nodeValue); current.appendChild(text); }	}	return current; }

// events function wa_attach(object, eventHandler, eventFunction, useCapture) { if ( useCapture == null ) useCapture = false; if (object.addEventListener) { if ( eventHandler == 'mouseenter' ) { object.addEventListener('mouseover', mouseMove( eventFunction ), useCapture); } else if ( eventHandler == 'mouseleave' ) { object.addEventListener('mouseout', mouseMove( eventFunction ), useCapture); } else { object.addEventListener(eventHandler, eventFunction, useCapture); }	} 	else { 		object.attachEvent('on' + eventHandler, eventFunction); } }

function mouseMove ( eventFunction ) { return function (e) { var target = e.relatedTarget; if ( ( this === target ) || ( wa_isChild ( target, this) ) ) { return; } eventFunction.call ( this, e ); }; }

function wa_isChild ( childTest, parentTest ) { if ( childTest === parentTest ) return false; while ( childTest && ( childTest !== parentTest ) ) { try { childTest = childTest.parentNode; } catch ( e ) { return true; } }	return ( childTest === parentTest ); }

function wa_getObjPos ( object ) { var curleft = curtop = 0; if ( object.offsetParent ) { do { curleft += object.offsetLeft; curtop += object.offsetTop; } while ( object = object.offsetParent ); }	return [ curleft, curtop ]; }

function mousex ( e ) { // read event, return mouse x pos if ( !e ) var e = window.event; if ( e.pageX ) { var r = e.pageX; } 	else if ( e.clientX ) { var r = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; }	return r; }

function mousey ( e ) { // read event, return mouse x pos if ( !e ) var e = window.event; if ( e.pageY ) { var r = e.pageY; } 	else if ( e.clientY ) { var r = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; }	return r; }

var wikiapps = true;

// Document ready here?

//main script function csdHelper { this.launch = function { // launch helper. check whether there is a deletion tag on this page. if ((document.getElementById('delete-criterion') != null) || (document.body.innerHTML.indexOf('speedy deletion of this page is contested.') > -1)) { if (wgNamespaceNumber == 10) { return false; // do nothing! } else { // all checks OK :).				// launch controller.				this.control	= new csdH_controller;				this.control.attachLinks;				return true;			}		} else { return false; /* do nothing!*/ }	} }

function csdH_controller { csdHController 		= this; this.notifyExempt	= new Array('SDPatrolBot','Ale jrb 2'); // these editors are exempt from being notified (if they added the tag, notification will fail) csdHController.deleteRegex = /[\s]*\{\{(?:db|speedy ?delet(?:e|ion)|speedy|d|rm|del(?:ete)? ?(?:because)?|csd|nn)(?:-(?:.+?))?(?:\|(?:.+?))?\}\}[\s]*/gi; csdHController.hangonRegex = /[\s]*\{\{(?:hang|hold)(?: |-)?oo?n(?:\|.+?)?\}\}[\s]*/gi; csdHController.doNotifyDec = ; csdHController.doNotifyDel = ; csdHController.doNotifyPrd = ''; if (notifyByDefaultDec == true) csdHController.doNotifyDec = ' checked'; if (notifyByDefaultDel == true) csdHController.doNotifyDel = ' checked'; if (notifyByDefaultPrd == true) csdHController.doNotifyPrd = ' checked'; if (notifyByDefaultNew == true) csdHController.doNotifyNew = ' checked'; if (waUser.isSysop == true) { csdHController.isSysop = 'yes'; csdHController.decAction = 'declined'; } else { csdHController.isSysop = 'no'; csdHController.decAction = 'contested'; } // default arrays - it's fine to edit these, but if you simply wish to add additional decline reasons, use the // setting for additional options described above. this.declineReasons = new Array(										['G1', 		'Not nonsense - there is meaningful content'],										['G2', 		'Not a test page'],										['G3', 		'Not blatantly vandalism or a hoax'],										['G4', 		'Not previously been deleted via a deletion discussion'],										['G5', 		'Not created by a banned user, or the page does not violate the user\'s ban'],										['G6', 		'Deletion of this page may be controversial or is under discussion'],										['G7', 		'Author has not requested deletion, or other users have added substantial content'],										['G8', 		'Does not rely on a page that does not exist'],										['G9', 		'G9 can only be used at the request of, or by, the Wikimedia Foundation'],										['G10', 	'Not blatantly an attack page or negative, unsourced BLP'],										['G11', 	'Not unambiguously promotional'],										['G12', 	'Not an unambiguous copyright infringement, or there is other content to save'], ['A1', 		'There is sufficient context to identify the subject of the article'], ['A2', 		'The article is in English, or does not exist at a foreign project'], ['A3', 		'Contains sufficient content to be a stub'], ['A5', 		'The article has not been transwikied to another project'], ['A7', 		'The article makes a credible assertion of importance or significance, sufficient to pass A7'], ['A7', 		'A7 does not apply to schools'], ['A7', 		'A7 does not apply to software'], ['A9', 		'The article makes a credible assertion of importance or significance, or is not a musical recording'], ['R2', 		'Does not redirect to a different or incorrect namespace'], ['R3', 		'Is a plausible, useful redirect or is not a redirect at all'], ['R3',		'Not a recently created redirect - consider WP:RfD'], ['U1', 		'Not a user page'], ['U1', 		'Does not apply to user talk pages'], ['U2', 		'User does exist, or this is not a user page'] );	this.deleteReasons = new Array( ['N/A', 	'You must select a rationale...'], ['G1', 		'Patent nonsense, meaningless, or incomprehensible'], ['G2', 		'Test page'], ['G3', 		'Vandalism'], ['G3', 		'Vandalism - blatant hoax or misinformation'], ['G4', 		'Recreation of a page that was deleted per a deletion discussion'], ['G5', 		'Creation by a banned user in violation of ban'], ['G6', 		'Housekeeping and routine (non-controversial) cleanup'], ['G7', 		'One author who has requested deletion or blanked the page'], ['G8', 		'Page dependent on a deleted or nonexistent page'], ['G8',		'Talk page of a deleted page'], ['G10', 	'Attack page or negative unsourced BLP that serves no purpose but to threaten or disparage its subject'], ['G11', 	'Unambiguous advertising or promotion'], ['G12', 	'Unambiguous copyright infringement'], ['G13', 	'Rejected or unsubmitted Articles for creation page that has not been edited in over six months'], ['A1', 		'Not enough context to identify article\'s subject'], ['A2', 		'Article in a foreign language that exists on another project'], ['A3', 		'Article that has no meaningful, substantive content'], ['A5', 		'Article that has been transwikied to another project'], ['A7', 		'No indication that the article may meet the guidelines for inclusion'], ['A7',		'Article about a real person, which does not indicate the importance or significance of the subject'], ['A7',		'Article about a band, singer, musician, or musical ensemble that does not indicate the importance or significance of the subject'], ['A7',		'Article about a web site, blog, web forum, webcomic, podcast, browser game, or similar web content, which does not indicate the importance or significance of the subject'], ['A7',		'Article about a company, corporation, organization, or group which does not indicate the importance or significance of the subject'], ['A7',		'Article about a group or club, which does not indicate the importance or significance of the subject'], ['A7',		'Article about an organized event, which does not indicate the importance or significance of the subject'], ['A7',		'Article about an individual animal, which does not indicate the importance or significance of the subject'], ['A9', 		'Article about a musical recording, which does not indicate the importance or significance of the subject and where the artist has no article'], ['A10', 	'Article where the only content is already existing in another article and where a redirect to the existing article would be implausible'], ['R2', 		'Cross-namespace redirect from mainspace'], ['R3', 		'Recently-created, implausible redirect'], ['U1', 		'User request to delete pages in own userspace'], ['U2', 		'Userpage or subpage of a nonexistent user'], ['U3', 		'Non-free gallery'] );	// Handle user defined content...	// declining	if (overwriteDeclineReasons == true) {		this.declineReasons.length = 0; this.declineReasons = myDeclineReasons;	} else {		this.declineReasons = this.declineReasons.concat(myDeclineReasons);	}	// deleting	if (overwriteDeleteReasons == true) {		this.deleteReasons.length = 0; this.deleteReasons = myDeleteReasons;	} else {		this.deleteReasons = this.deleteReasons.concat(myDeleteReasons);	}	// append necessary options to decline reasons	var declineReasonsEnd = new Array( ['INVALID', 		'The reason given is not a valid speedy deletion criterion'],	// don't touch this ['DONTPROVIDE', 	'No reason given.'], 						// don't touch this ['OTHER', 			'Other - provide your own reason below']	// don't touch this );	this.declineReasons = this.declineReasons.concat(declineReasonsEnd);	// main GUI function	this.showcsdHWindow = function {		// grab position of button		var offsetL = 0, offsetT = 0, thisObject = document.getElementById('ca-speedy');		if ( thisObject.offsetParent ) {			do {				offsetL += thisObject.offsetLeft;				offsetT += thisObject.offsetTop;			} while ( thisObject = thisObject.offsetParent );		}		// build window to show user		if (waUser.isSysop == true) { var showSys = 'Delete Page ' } else { var showSys = ''; }		if (this.interface == null) { 			this.interface = new wa_window(document.getElementById('content')); this.visible = true; this.csdHelperLink.ele_obj.setAttribute('class', 'selected'); this.interface.win_content = ''+ ' Handle Speedy Deletion '+ ' What do you want to do to this page? '+								' '+									showSys+ 'Decline Speedy '+ 'Change to PROD '+ ' '+								'';		} else { this.interface.win_content = ''+ ' Handle Speedy Deletion '+ ' What do you want to do to this page? '+								' '+									showSys+ 'Decline Speedy '+ 'Change to PROD '+ ' '+								'';			if (this.visible == true) { this.csdHelperLink.ele_obj.setAttribute('class', ''); this.interface.win_disp = 'none'; this.interface.applyAll; this.visible = false; return true; } else { this.csdHelperLink.ele_obj.setAttribute('class', 'selected'); this.interface.win_disp = 'block'; this.interface.win_height = 170; this.interface.applyAll; this.visible = true; return true; }		}		if ( mw.config.get ( 'skin' ) == 'vector' ) { this.interface.win_left = offsetL - 17; this.interface.win_top = offsetT + 39; } else { this.interface.win_left = document.getElementById('ca-speedy').offsetLeft - 17; this.interface.win_top = -1; }		this.interface.win_width = 600; this.interface.win_height = 170; this.interface.win_bg = '#fff'; this.interface.win_bd = '#aaaaaa'; this.interface.win_bd_wd = 1; this.interface.applyAll; }	this.declinePage = function { // build the selection options var declineOptions = ''; var optionSelected = false; for (var i = 0; i < this.declineReasons.length; i++) { var selected = ''; // determine whether this option should be selected if (optionSelected == false) { if (document.getElementById('delete-criterion') != null) { // if this matches the criterion provided, select it. if (document.getElementById('delete-criterion').innerHTML == this.declineReasons[i][0]) { selected = ' selected '; optionSelected = true; } if ( (this.declineReasons[i][0] == 'INVALID') && (optionSelected == false) ) { selected = ' selected '; optionSelected = true; } } else { // if no criterion was selected, wait until 'other' is selected. if (this.declineReasons[i][0] == 'OTHER') { selected = ' selected '; optionSelected = true; } }			}			// build the visible message for use in the drop-down. var tempVisible = myDeclineListing.replace(/%CRITERION%/gi, this.declineReasons[i][0]); tempVisible = tempVisible.replace(/%REASON%/gi, this.declineReasons[i][1]); declineOptions += ''+tempVisible+' '; }		if ( mw.config.get ( 'skin' ) == 'vector' ) { var skinPos = '3'; } else { var skinPos = '10'; } this.interface.win_content = ''+ ' Decline Speedy Deletion '+ ' Select the reason for declining the deletion from the list. This text will be used as the edit summary. '+								''+declineOptions+' '+ ' Or provide your own reason and summary below. '+								''+ ' -- decline speedy deletion -- '+ 'notify tagger  '+ 'use newbie message  '+ ' '+								'';		this.interface.applyAll; }	this.declineDo = function(callback) { // get page content if (!callback) var callback = 0; switch (callback) { default: // main vars csdHController.declineText = 	document.getElementById('declineText').value; csdHController.declineSel = 	document.getElementById('declineReason').selectedIndex; csdHController.declineNotify = 	document.getElementById('notifyTagger').checked; csdHController.notifyNewbie = 	document.getElementById('notifyNewbie').checked; if ((csdHController.declineText == '') && (csdHController.declineSel == csdHController.declineReasons.length-1)) { // if no reason is typed, byt 'Other' is selected, use the 'No reason provided' option. csdHController.declineSel = csdHController.declineReasons.length - 2; }				csdHController.declineCategory 	= 	csdHController.declineReasons[csdHController.declineSel][0]; csdHController.declineReason 	=	csdHController.declineReasons[csdHController.declineSel][1]; // build all messages if ( (csdHController.declineCategory == 'INVALID') || (csdHController.declineCategory == 'DONTPROVIDE') ) { // if it's a 'special' case, use the 'special' summary var tempSummary = myDeclineSummarySpecial; tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineReason); csdHController.editSummary = tempSummary; } else if (csdHController.declineCategory == 'OTHER') { // if they've typed a reason, use that var tempSummary = myDeclineSummarySpecial; tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineText); csdHController.editSummary = tempSummary; } else { // otherwise, use the 'normal' summary var tempSummary = myDeclineSummary; tempSummary = tempSummary.replace(/%ACTION%/gi, csdHController.decAction); tempSummary = tempSummary.replace(/%CRITERION%/gi, csdHController.declineCategory); tempSummary = tempSummary.replace(/%REASON%/gi, csdHController.declineReason); csdHController.editSummary = tempSummary; }				csdHController.editSummary += ' (CSDH)'; // start this.interface.win_content = ''+ ' Working... '+								' Please wait while CSDHelper performs the requested operations. This can take several seconds. '+								' - Retrieving existing content... '+								' '+								'';				this.interface.applyAll; csdHController.pageReq = new wa_mediawikiApi; csdHController.pageReq.onCompleteAction = function { csdHController.declineDo('1'); }; csdHController.pageReq.getPage(wgPageName, notifyLimit, 'user|content'); break; case '1': document.getElementById('workingStatus').innerHTML += '- Removing tags... ';				csdHController.pageContent = csdHController.pageReq.data['page']['revisions'][0]['content']; var regReplace = csdHController.deleteRegex; csdHController.pageContent = csdHController.pageContent.replace(regReplace, ''); var regReplace = csdHController.hangonRegex; csdHController.pageContent = csdHController.pageContent.replace(regReplace, ''); csdHController.newContent = csdHController.pageContent; // grab a record of that document.getElementById('workingStatus').innerHTML += '- Updating page... ';				csdHController.editReq = new wa_mediawikiApi; csdHController.editReq.onCompleteAction = function { csdHController.declineDo('2'); }; csdHController.editReq.editPage(wgPageName, csdHController.newContent, csdHController.editSummary, false, 'text'); break; case '2': // check for notify if ( (csdHController.declineNotify == true) || (logOnDecline == true) ) { document.getElementById('workingStatus').innerHTML += '- Determining user who tagged page... ';					var tags = 0; csdHController.tagger = ''; for (var i = 0; i < notifyLimit; i ++) { var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content']; // count tags var regTest = csdHController.deleteRegex; var k = 1; var count = 0; while (k != null) { k = regTest.exec(thisPage); if (k != null) count ++; }						regTest.lastIndex = 0; // check if we have fewer than last time (1 was added on that rev) if (count < tags) { csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user']; break; } else { tags = count; }					}					if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger: will not log or notify. Finished. '; break; } for (var i = 0; i < csdHController.notifyExempt.length; i ++) { if (csdHController.tagger == csdHController.notifyExempt[i]) { document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Finished. ';							if (logOnDecline == true) { csdHController.declineNotify = false; csdHController.declineDo('3'); } else { return true; } }					}					if ( (logOnDecline == true) && (logOnDeclinePath != '') ) { csdHController.declineDo('3'); } else { csdHController.declineDo('5'); } } else { window.location.reload(true); csdHController.showcsdHWindow; } break; case '3': // log decline action where relevant document.getElementById('workingStatus').innerHTML += '- Logging decline action to \''+logOnDeclinePath+'\' - retrieving page... ';				csdHController.pageReq = new wa_mediawikiApi; csdHController.pageReq.onCompleteAction = function { csdHController.declineDo('4'); }; csdHController.pageReq.getPage(logOnDeclinePath, 1, 'content'); break; case '4': // we have retrieved the data regarding the log page; move to edit it document.getElementById('workingStatus').innerHTML += 'modifying page... ';				//var logOnDeclinePath = logOnDeclinePath.replace(/ /g,'_'); // check whether there is existing content var pageData = csdHController.pageReq.data['page']; if (pageData['status'] == 'OK') { var oldContent = pageData['revisions'][0]['content']; if ( oldContent === '' ) oldContent = "{| class=\"sortable wikitable\" style=\"font-size: 80%;\" border=\"2\" cellpadding=\"1\" background:#f9f9f9;\"|\n|-\n! style=\"text-align: left\" | Article\n! Tagger\n! Criterion\n! Decline reason\n! Date\n|}";				} else {					var oldContent = "{| class=\"sortable wikitable\" style=\"font-size: 80%;\" border=\"2\" cellpadding=\"1\" background:#f9f9f9;\"|\n|-\n! style=\"text-align: left\" | Article\n! Tagger\n! Criterion\n! Decline reason\n! Date\n|}"; }				// message var pageName = wgPageName.replace(/_/g, ' '); var reason = (csdHController.declineCategory == 'OTHER') ? csdHController.declineText : csdHController.declineReason; var crit = document.getElementById('delete-criterion').innerHTML; var message = "|-\n| " + pageName + " || " + csdHController.tagger + " || CSD " + crit + " || " +reason + " || " + "" + "" + "~\n"; // add the new row to the table var newContent = oldContent.replace('|}', message + '|}'); // build vars var editSummary = 'Adding ' + pageName + ' to speedy decline log (CSDH)'; // perform the edit csdHController.editReq = new wa_mediawikiApi; csdHController.editReq.onCompleteAction = function { csdHController.declineDo('5'); }; csdHController.editReq.editPage(logOnDeclinePath, newContent, editSummary, true, 'text'); break; case '5': // check notify if (csdHController.declineNotify != true) { window.location.reload(true); csdHController.showcsdHWindow; break; } // output document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user... ';				// edit summary csdHController.editSummary = 'Notifying about '+csdHController.decAction+' speedy deletion (CSDH)'; // decide whether to use newbie message if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; } // fix message - handle other special case if (csdHController.declineCategory == 'OTHER') csdHController.declineReason = csdHController.declineText; // fix message - handle punctuation at the end of the message (it must be added if absent). var p = csdHController.declineReason.substr(csdHController.declineReason.length - 1); if ( (p != '.') && (p != '!') && (p != '?') ) csdHController.declineReason += '.'; // message var message = '== Speedy deletion '+csdHController.decAction+': '+wgPageName.replace(/_/g, ' ')+' =='+"\n"+' '+''; csdHController.saveReq = new wa_mediawikiApi; csdHController.saveReq.onCompleteAction = function { window.location.reload(true); csdHController.showcsdHWindow; }; csdHController.saveReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext'); break; }	}	this.prodPage = function { var prodOptions = ''; var content = document.getElementById('bodyContent'); var regTest = /criteria for speedy deletion<\/a><\/i> because (.*?)\.<\/b> For valid criteria,/i var rationale = regTest.exec(content); if (rationale != null) { rationale = rationale[1]; } else { rationale = ''; } this.interface.win_content = ''+ ' Convert to PROD '+ ' You are asserting that the page cannot be speedy deleted, but can be deleted by proposed deletion. '+								'Enter the reason for deletion below - if the tagger provided one, it will be filled automatically. '+								''+ '<div id="notifyTaggerDiv" style="margin-top: 10px; font-size: 11px; margin-left: 20px; float: left; vertical-align: middle;">notify tagger of conversion <input id="notifyTagger"'+csdHController.doNotifyPrd+' style="position: relative; top: 3px; " type="checkbox" /> '+								'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /> '+ ' -- <a href="#" onclick="csdHController.prodDo;">convert to PROD</a> -- '+ ' '+								'';		this.interface.applyAll; }	this.prodDo = function(callback) { if (!callback) var callback = 0; switch (callback) { default: csdHController.prodReason = document.getElementById('prodReason').value; csdHController.prodNotify = document.getElementById('notifyTagger').checked; csdHController.notifyNewbie = document.getElementById('notifyNewbie').checked; this.interface.win_content = ''+ ' Working... '+								' Please wait while CSDHelper performs the requested operations. This can take several seconds. '+								' '+								' '+								'';				this.interface.applyAll; if (csdHController.prodNotify == true) { document.getElementById('workingStatus').innerHTML += '- Searching for tagger... ';					if (notifyLimit > 15) notifyLimit = 15; csdHController.pageReq = new wa_mediawikiApi; csdHController.pageReq.onCompleteAction = function { csdHController.prodDo('1'); }; csdHController.pageReq.getPage(wgPageName, notifyLimit + 1, 'content|user'); } else { csdHController.pageReq = new wa_mediawikiApi; csdHController.pageReq.onCompleteAction = function { csdHController.prodDo('3'); }; csdHController.pageReq.getPage(wgPageName, 1, 'content|user'); }				break; case '1': var tags = 0; csdHController.tagger = ''; for (var i = 0; i < notifyLimit; i ++) { var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content']; // count tags var regTest = csdHController.deleteRegex; var k = 1; var count = 0; while (k != null) { k = regTest.exec(thisPage); if (k != null) count ++; }					regTest.lastIndex = 0; // check if we have fewer than last time (1 was added on that rev) if (count < tags) { csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user']; break; } else { tags = count; }				}				if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger. Moving to tag page... '; csdHController.prodDo('3'); break; } for (var i = 0; i < csdHController.notifyExempt.length; i ++) { if (csdHController.tagger == csdHController.notifyExempt[i]) { document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Moving to tag page... ';						csdHController.prodDo('3'); return true; }				}				csdHController.prodDo('2'); break; case '2': // notify tagger document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user... ';				// edit summary csdHController.editSummary = 'Notifying about speedy deletion converted to PROD (CSDH)'; // decide whether to use newbie message if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; } // message var message = '== Speedy deletion converted to PROD: '+wgPageName.replace(/_/g, ' ')+' =='+"\n"+' '+''; csdHController.notifyReq = new wa_mediawikiApi; csdHController.notifyReq.onCompleteAction = function { csdHController.prodDo('3'); }; csdHController.notifyReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext'); break; case '3': document.getElementById('workingStatus').innerHTML += '- Converting tags... ';				csdHController.pageContent = csdHController.pageReq.data['page']['revisions'][0]['content']; var regReplace = csdHController.deleteRegex; csdHController.pageContent = csdHController.pageContent.replace(regReplace, ''); var regReplace = csdHController.hangonRegex; csdHController.pageContent = csdHController.pageContent.replace(regReplace, ''); if (csdHController.prodReason != 'nn') { csdHController.pageContent = '{'+'{subst:prod|'+csdHController.prodReason+'}'+'}\n' + csdHController.pageContent; } else { csdHController.pageContent = '{'+'{subst:prod-nn}'+'}\n' + csdHController.pageContent; } csdHController.newContent = csdHController.pageContent; // grab a record of that csdHController.editSummary = 'Speedy deletion converted to PROD (CSDH)'; document.getElementById('workingStatus').innerHTML += '- Updating page... ';				csdHController.editReq = new wa_mediawikiApi; csdHController.editReq.onCompleteAction = function { window.location.reload(true); csdHController.showcsdHWindow; }; csdHController.editReq.editPage(wgPageName, csdHController.newContent, csdHController.editSummary, false, 'text'); break; }	}	this.deletePage = function { // build the selection options var deleteOptions = ''; var optionSelected = false; for (var i = 0; i < this.deleteReasons.length; i++) { var selected = ''; if ( (document.getElementById('delete-criterion') != null) && (optionSelected == false) ) { if (document.getElementById('delete-criterion').innerHTML == this.deleteReasons[i][0]) { csdHController.initialRationale = this.deleteReasons[i][0]; selected = ' selected'; optionSelected = true; } } else { if (this.deleteReasons[i][0] == 'N/A') { selected = ' selected '; optionSelected = true; } }			// general var visibleReasoning = this.deleteReasons[i][1].replace(/\[\[(?:.*?\|)(.+?)\]\]/g, '$1'); deleteOptions += '<option value="'+i+'"'+selected+'>'+this.deleteReasons[i][0]+': '+visibleReasoning+' '; }		if (document.getElementById('delete-criterion') == null) { var displayTagCommand = 'display: none;'; } else { var displayTagCommand = 'display: block;'; } this.interface.win_content = ''+ ' Perform Speedy Deletion '+ ' Select the reason for deletion from the list. The rationale specified by the tagger is automatically selected. If you select a reason that does not '+ 'match the tag, will be given the option of notifying the tagger. '+								'<select id="deleteReason" style="font-size: 11px; margin-left: 9px; width: 576px;" onchange="'+									'if (document.getElementById(\'delete-criterion\') != null) {'+										'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] != document.getElementById(\'delete-criterion\').innerHTML) { '+											'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] == \'N/A\') { document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; } else { document.getElementById(\'notifyTaggerDiv\').style.display = \'block\'; }'+										'} else {'+											'document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; '+										'}'+									'} else { document.getElementById(\'notifyTaggerDiv\').style.display = \'none\'; }'+									'if (csdHController.deleteReasons[document.getElementById(\'deleteReason\').selectedIndex][0] == \'N/A\') {'+ 'document.getElementById(\'performDeletionDiv\').style.display = \'none\'; '+ '} else {'+ 'document.getElementById(\'performDeletionDiv\').style.display = \'block\'; '+ '}'+								'">'+deleteOptions+' '+								'<div id="notifyTaggerDiv" style="display: none; margin-top: 10px; font-size: 11px; margin-left: 20px; float: left; vertical-align: middle;">notify tagger of rationale change <input id="notifyTagger"'+csdHController.doNotifyDel+' style="position: relative; top: 3px; " type="checkbox" /> '+								'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /> '+								'<div id="performDeletionDiv" style="margin: auto; margin-top: 13px; font-size: 11px; width: 200px; text-align: center; '+displayTagCommand+'">-- <a href="#" onclick="csdHController.deleteDo;">perform speedy deletion</a> -- '+								' '+								'';		this.interface.applyAll;	}	this.deleteDo = function(callback) {		if (!callback) var callback = 0;		switch (callback) {			default:				csdHController.deleteSel 		= document.getElementById('deleteReason').selectedIndex; csdHController.deleteNotify 	= document.getElementById('notifyTagger').checked; csdHController.notifyNewbie		= document.getElementById('notifyNewbie').checked; if (document.getElementById('delete-criterion') == null) { csdHController.allowDelNotify = false; } else { csdHController.allowDelNotify = (csdHController.deleteReasons[csdHController.deleteSel][0] != document.getElementById('delete-criterion').innerHTML); } this.interface.win_content = ''+ ' Working... '+								' Please wait while CSDHelper performs the requested operations. This can take several seconds. '+								' '+								' '+								'';				this.interface.applyAll; if ((csdHController.deleteNotify == true) && (csdHController.allowDelNotify == true)) { document.getElementById('workingStatus').innerHTML += '- Searching for tagger... ';					if (notifyLimit > 15) notifyLimit = 15; csdHController.pageReq = new wa_mediawikiApi; csdHController.pageReq.onCompleteAction = function { csdHController.deleteDo('1'); }; csdHController.pageReq.getPage(wgPageName, notifyLimit + 1, 'content|user'); } else { csdHController.deleteDo('3'); } break; case '1': var tags = 0; csdHController.tagger = ''; for (var i = 0; i < notifyLimit; i ++) { var thisPage = csdHController.pageReq.data['page']['revisions'][i]['content']; // count tags var regTest = csdHController.deleteRegex; var k = 1; var count = 0; while (k != null) { k = regTest.exec(thisPage); if (k != null) count ++; }					regTest.lastIndex = 0; // check if we have fewer than last time (1 was added on that rev) if (count < tags) { csdHController.tagger = csdHController.pageReq.data['page']['revisions'][i - 1]['user']; break; } else { tags = count; }				}				if (csdHController.tagger == '') { document.getElementById('workingStatus').innerHTML += '- Could not determine tagger. Moving to deletion... '; csdHController.deleteDo('3'); break; } for (var i = 0; i < csdHController.notifyExempt.length; i ++) { if (csdHController.tagger == csdHController.notifyExempt[i]) { document.getElementById('workingStatus').innerHTML += '- Tagger ('+csdHController.tagger+') is on the tagger exempt list, and will not be notified. Moving to deletion... ';						csdHController.deleteDo('3'); return true; }				}				csdHController.deleteDo('2'); break; case '2': // notify tagger document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user... ';				// edit summary csdHController.editSummary = 'Notifying about altered speedy deletion rationale (CSDH)'; // decide whether to use newbie message if (csdHController.notifyNewbie) { var useNewbie = 'yes'; } else { var useNewbie = 'no'; } // message var message = '== Altered speedy deletion rationale: '+wgPageName.replace(/_/g, ' ')+' =='+"\n"+' '+''; csdHController.notifyReq = new wa_mediawikiApi; csdHController.notifyReq.onCompleteAction = function { csdHController.deleteDo('3'); }; csdHController.notifyReq.editPage('User_talk:'+csdHController.tagger, message, csdHController.editSummary, false, 'appendtext'); break; case '3': // perform the edit document.getElementById('workingStatus').innerHTML += '- Deleting page... ';				var deleteReason = ''+csdHController.deleteReasons[csdHController.deleteSel][0]+': ' + csdHController.deleteReasons[csdHController.deleteSel][1] + ' (CSDH)'; csdHController.deleteReq = new wa_mediawikiApi; csdHController.deleteReq.onCompleteAction = function(callback) { if ( (callback == null) || (callback == false) || (wgNamespaceNumber != 0) ) { // no talk page window.location = redirectAfterDel; csdHController.showcsdHWindow; } else { // talk page exists csdHController.talkpageId = callback; document.getElementById('workingStatus').innerHTML = ''+ ' Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?

'+																							' <a href="#" onclick="document.getElementById(\'workingStatus\').innerHTML = \'- Deleting talk page... \'; csdHController.deleteDo(\'4\');">Delete</a> | <a href="#" onclick="window.location = redirectAfterDel; csdHController.showcsdHWindow; ">Ignore</a> '+ '';																					}																				};				csdHController.deleteReq.performAction('delete', wgPageName, deleteReason); break; case '4': // delete the talk page - get the title var talkPage = 'Talk:' + wgPageName; csdHController.deleteReq = new wa_mediawikiApi; csdHController.deleteReq.onCompleteAction = function { window.location = redirectAfterDel; csdHController.showcsdHWindow; }; csdHController.deleteReq.performAction('delete', talkPage, 'G8: Talk page of deleted page. (CSDH)'); break; }	}	this.displayError = function { this.interface.win_content = ''+ ' An error occurred... '+								' '+								'';		this.interface.applyAll; }	this.attachLinks = function { this.csdHelperLink 						= new wa_element('li'); this.csdHelperLink.ele_obj.id			= 'ca-speedy'; this.csdHelperLink.addScriptEvent('click', function { csdHController.showcsdHWindow; }); if ( mw.config.get ( 'skin' ) == 'vector' ) { this.csdHelperLink.ele_obj.innerHTML	= ' <a href="#" title="handle speedy deletion">Speedy</a> '; this.csdHelperLink.attach(document.getElementById('ca-talk'), 'after'); } else { this.csdHelperLink.ele_obj.innerHTML	= '<a href="#" title="handle speedy deletion">speedy</a>'; this.csdHelperLink.attach(document.getElementById('ca-move'), 'before'); }	}; }

function launchCsdHelper { // lib proto wa_window.prototype = new wa_document; wa_element.prototype = new wa_document; // init object var obj_csdHelper = new csdHelper; obj_csdHelper.launch ; return true; }

$(document).ready( function { launchCsdHelper });