User:Equazcion/csdhelper.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Equazcion/csdhelper. |
/* ============================================== *\
** 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.
\* ============================================== */
// 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
\* ============================================== */
// 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', '[[WP:PN|Patent nonsense]], meaningless, or incomprehensible'],
['G2', 'Test page'],
['G3', '[[WP:VANDAL|Vandalism]]'],
['G3', '[[WP:VANDAL|Vandalism]] - blatant hoax or misinformation'],
['G4', 'Recreation of a page that was [[WP:DEL|deleted]] per a [[WP:XFD|deletion discussion]]'],
['G5', 'Creation by a [[WP:BAN|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', '[[WP:ATP|Attack page]] or negative unsourced [[WP:BLP|BLP]] that serves no purpose but to threaten or disparage its subject'],
['G11', 'Unambiguous [[WP:ADS|advertising]] or promotion'],
['G12', 'Unambiguous [[WP:C|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-[[WP:NS|namespace]] [[WP:R|redirect]] from mainspace'],
['R3', 'Recently-created, implausible [[WP:R|redirect]]'],
['U1', 'User request to delete pages in own userspace'],
['U2', 'Userpage or subpage of a nonexistent user'],
['U3', '[[WP:NFC|Non-free]] [[Help:Gallery|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 [[WP:CSD|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 = '<div style="margin: auto; width: 95%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 22px; margin-top: 20px;" onclick="csdHController.deletePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Delete Page</div>' } 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 = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>'+
'<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>'+
'<div style="font-size: 11px; text-align: center; width: 100%;">'+
showSys+
'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>'+
'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>'+
'</div>'+
'';
} else {
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Handle Speedy Deletion</div>'+
'<div style="font-size: 11px; margin-left: 7px;">What do you want to do to this page?</div>'+
'<div style="font-size: 11px; text-align: center; width: 100%;">'+
showSys+
'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 20px;" onclick="csdHController.declinePage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Decline Speedy</div>'+
'<div style="margin: auto; width: 80%; cursor: pointer; background: #dfdfdf; border: 1px solid #cfcfcf; height: 16px; margin-top: 5px;" onclick="csdHController.prodPage();" onmouseover="this.style.border = \'1px solid #333333\';" onmouseout="this.style.border = \'1px solid #cfcfcf\';">Change to PROD</div>'+
'</div>'+
'';
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 += '<option'+selected+'>'+tempVisible+'</option>';
}
if ( mw.config.get ( 'skin' ) == 'vector' ) { var skinPos = '3'; } else { var skinPos = '10'; }
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Decline Speedy Deletion</div>'+
'<div style="font-size: 11px; margin-left: 7px; padding: 0px;">Select the reason for declining the deletion from the list. This text will be used as the edit summary.</div>'+
'<select id="declineReason" style="font-size: 11px; margin-left: 9px;" onchange="document.getElementById(\'declineText\').value = \'\'">'+declineOptions+'</select>'+
'<div style="font-size: 11px; margin-left: 7px; margin-top: 8px; padding: 0px;">Or provide your own reason and summary below.</div>'+
'<input id="declineText" style="margin-left: 9px; font-size: 11px; width: 576px;" type="text" onkeyup="document.getElementById(\'declineReason\').selectedIndex = csdHController.declineReasons.length-1;" />'+
'<div style="margin-top: 13px; float: right; margin-right: 300px; font-size: 11px; ">-- <a href="#" onclick="csdHController.declineDo();">decline speedy deletion</a> --</div>'+
'<div style="margin-top: '+skinPos+'px; font-size: 11px; margin-left: 20px; vertical-align: middle; padding: 0px;">notify tagger <input id="notifyTagger"'+csdHController.doNotifyDec+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
'<div style="margin-top: '+skinPos+'px; font-size: 11px; margin-left: 20px; vertical-align: middle; padding: 0px;">use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
'</div>'+
'';
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 += ' ([[User:Ale_jrb/Scripts|CSDH]])';
// start
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
'<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
'<div id="workingStatus" style="font-size: 11px; margin-left: 15px;">- Retrieving existing content...<br /></div>'+
'</div>'+
'';
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...<br />';
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...<br />';
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...<br />';
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.<br />'; 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.<br />';
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...<br />';
//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 + "]] || [[User:" + csdHController.tagger + "|" + csdHController.tagger + "]] || [[WP:CSD#" + crit + "|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 ([[User:Ale_jrb/Scripts|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...<br />';
// edit summary
csdHController.editSummary = 'Notifying about '+csdHController.decAction+' speedy deletion ([[User:Ale_jrb/Scripts|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"+'{{subst:'+notifyTemplate+'|action=decline|page='+wgPageName.replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|declinetext='+csdHController.declineReason+'|admin='+csdHController.isSysop+'|newbie='+useNewbie+'}} ~~'+'~~';
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> <i>For valid criteria,/i
var rationale = regTest.exec(content);
if (rationale != null) { rationale = rationale[1]; } else { rationale = ''; }
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Convert to PROD</div>'+
'<div style="font-size: 11px; margin-left: 7px;">You are asserting that the page cannot be speedy deleted, but <em>can</em> be deleted by proposed deletion. '+
'Enter the reason for deletion below - if the tagger provided one, it will be filled automatically.</div>'+
'<input id="prodReason" style="margin-left: 9px; font-size: 11px; width: 576px;" type="text" value="'+rationale+'" />'+
'<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" /><br />'+
'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
'<div style="margin: auto; margin-top: 13px; font-size: 11px; width: 200px; text-align: center;">-- <a href="#" onclick="csdHController.prodDo();">convert to PROD</a> --</div>'+
'</div>'+
'';
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 = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
'<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
'<div id="workingStatus" style="font-size: 11px; margin-left: 15px;"></div>'+
'</div>'+
'';
this.interface.applyAll();
if (csdHController.prodNotify == true) {
document.getElementById('workingStatus').innerHTML += '- Searching for tagger...<br />';
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...<br />'; 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...<br />';
csdHController.prodDo('3');
return true;
}
}
csdHController.prodDo('2');
break;
case '2': // notify tagger
document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...<br />';
// edit summary
csdHController.editSummary = 'Notifying about speedy deletion converted to PROD ([[User:Ale_jrb/Scripts|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"+'{{subst:'+notifyTemplate+'|action=convert|page='+wgPageName.replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|admin='+csdHController.isSysop+'|newbie='+useNewbie+'}} ~~'+'~~';
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...<br />';
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 ([[User:Ale_jrb/Scripts|CSDH]])';
document.getElementById('workingStatus').innerHTML += '- Updating page...<br />';
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+'</option>';
}
if (document.getElementById('delete-criterion') == null) { var displayTagCommand = 'display: none;'; } else { var displayTagCommand = 'display: block;'; }
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Perform Speedy Deletion</div>'+
'<div style="font-size: 11px; margin-left: 7px;">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.</div>'+
'<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+'</select>'+
'<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" /><br />'+
'use newbie message <input id="notifyNewbie"'+csdHController.doNotifyNew+' style="position: relative; top: 3px; " type="checkbox" /></div>'+
'<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> --</div>'+
'</div>'+
'';
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 = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">Working...</div>'+
'<div style="font-size: 11px; margin-left: 7px;">Please wait while CSDHelper performs the requested operations. This can take several seconds.</div>'+
'<div id="workingStatus" style="font-size: 11px; margin-left: 15px;"></div>'+
'</div>'+
'';
this.interface.applyAll();
if ((csdHController.deleteNotify == true) && (csdHController.allowDelNotify == true)) {
document.getElementById('workingStatus').innerHTML += '- Searching for tagger...<br />';
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...<br />'; 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...<br />';
csdHController.deleteDo('3');
return true;
}
}
csdHController.deleteDo('2');
break;
case '2': // notify tagger
document.getElementById('workingStatus').innerHTML += '- Tagged by \''+csdHController.tagger+'\' - notifying user...<br />';
// edit summary
csdHController.editSummary = 'Notifying about altered speedy deletion rationale ([[User:Ale_jrb/Scripts|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"+'{{subst:'+notifyTemplate+'|action=change|page='+wgPageName.replace(/_/g, ' ')+'|tagger='+csdHController.tagger+'|newbie='+useNewbie+'}} ~~'+'~~';
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...<br />';
var deleteReason = '[[WP:CSD#'+csdHController.deleteReasons[csdHController.deleteSel][0]+'|'+csdHController.deleteReasons[csdHController.deleteSel][0]+']]: ' + csdHController.deleteReasons[csdHController.deleteSel][1] + ' ([[User:Ale_jrb/Scripts|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 = ''+
'<strong>Warning: this page now has an orphaned talk page. Do you wish to delete it under G8?</strong><br /><br />'+
'<div style="width: 100%; text-align: center;"><a href="#" onclick="document.getElementById(\'workingStatus\').innerHTML = \'- Deleting talk page...<br />\'; csdHController.deleteDo(\'4\');">Delete</a> | <a href="#" onclick="window.location = redirectAfterDel; csdHController.showcsdHWindow(); ">Ignore</a></div>'+
'';
}
};
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, '[[WP:CSD#G8|G8]]: Talk page of deleted page. ([[User:Ale_jrb/Scripts|CSDH]])');
break;
}
}
this.displayError = function() {
this.interface.win_content = ''+
'<div><div style="width: 596px; border-bottom: 1px solid #aaaaaa; padding: 2px; font-weight: bold;">An error occurred...</div>'+
'</div>'+
'';
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 = '<span><a href="#" title="handle speedy deletion">Speedy</a></span>';
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() });