User:John Vandenberg/delsort.js

// Wikipedia:WikiProject Deletion sorting

// This is a development version of Wikipedia:WikiProject Deletion sorting/delsort.js

if( typeof( DelsortConfig ) == 'undefined' ) {

DelsortConfig = function() {};

}

DelsortConfig.compactPage = 'Wikipedia:WikiProject_Deletion_sorting/Compact';

var Delsort = function() {};

// Used to emulate CSS columns in Opera

function add_opera_delsort_compact_css() {

if ( wgNamespaceNumber == 4 && wgPageName == DelsortConfig.compactPage ) {

if( navigator.userAgent.indexOf("Opera") != -1 ) {

importStylesheet('Wikipedia:WikiProject Deletion sorting/compact opera.css');

}

}

}

// adds 'delsort' tab to p-cactions

function add_delsort_tab()

{

if ( DelsortConfig['debugLevel'] > 0 ) {

Delsort.displayPopup( '', "Setting up buttons.." );

Status.init( window['delsortWindow'].content );

Delsort.debug ('Adding delsort button ...');

}

var tabs = document.getElementById('p-cactions').getElementsByTagName('ul')[0];

var ul = addlimenu(tabs, 'delsort', 'delsort');

if ( DelsortConfig['debugLevel'] > 0 ) Delsort.debug ('ul = ' + ul.tagName);

var menuitem = ul.previousSibling;

menuitem.setAttribute('href','javascript:showDelsortFrame()');

// when the user is in edit mode, save a reference to it

Delsort.afdForm = document.getElementById( 'editform' );

// support deprecated shortcut list

if ( window['delsortPages'] )

DelsortConfig.shortcuts = window['delsortPages'];

// add each shortcut

if ( DelsortConfig['shortcuts'] &&

DelsortConfig['shortcuts']['length'] ) {

for (i = 0; i < DelsortConfig.shortcuts.length; i++) {

if ( DelsortConfig['debugLevel'] > 0 ) Delsort.debug ('adding shortcut "' +

DelsortConfig.shortcuts[i] + '"');

mw.util.addPortletLink('delsort',

'javascript:delsortArticle("' + DelsortConfig.shortcuts[i] + '")',

DelsortConfig.shortcuts[i],

'');

}

}

if ( DelsortConfig['debugLevel'] > 0 ) {

Delsort.debug ('done');

}

}

Delsort.add_inline_ui = function() {

if ( DelsortConfig['debugLevel'] > 0 ) {

Delsort.displayPopup( '', "Setting up inline delsort buttons.." );

Status.init( window['delsortWindow'].content );

Delsort.debug ('Adding delsort to ...');

}

var spans = document.getElementsByTagName('SPAN');

for (i = 0; i < spans.length; i++) {

if (spans[i].className == 'editsection') {

// spans[i] is a section, which is usually the start of a transclude.

// It could be a section within the transcluded page

var sectionEditAnchor = spans[i].getElementsByTagName('A');

if ( sectionEditAnchor ) sectionEditAnchor = sectionEditAnchor[0];

Delsort.debug ('-- Found section "' + sectionEditAnchor.title + '"');

if ( sectionEditAnchor && /Wikipedia:Articles for deletion/.exec ( sectionEditAnchor.title ) ) {

window['wgAfdPage'] = sectionEditAnchor.title;

Delsort.debug ('Looking for more signs that "' + sectionEditAnchor.title + '" is an Afd...');

}

else {

window['wgAfdPage'] = '';

}

}

if (window['wgAfdPage'] && spans[i].className == 'mw-headline') {

// span[i] is the beginning of the transcluded Afd content

if ( window['wgAfdPage'].indexOf ( spans[i].textContent ) > -1 ) {

window['wgNominatedArticle'] = spans[i].textContent;

Delsort.debug (' ' + window['wgAfdPage'] + ': ' + window['wgNominatedArticle']);

parentNode = spans[i].parentNode;

var laNode = null;

// try looking for {{la|...}} directly after

if (parentNode.nextSibling.nodeValue == '\n' &&

parentNode.nextSibling.nextSibling.tagName == 'DL' ) {

// looks like we have found {{la|...}}

laNode = parentNode.nextSibling.nextSibling;

}

// try looking for {{la|...}} by skipping a "AfDs for this article" DIV

if (parentNode.nextSibling.nodeValue == '\n' &&

parentNode.nextSibling.nextSibling.tagName == 'DIV' &&

parentNode.nextSibling.nextSibling.nextSibling.nodeValue == '\n' &&

parentNode.nextSibling.nextSibling.nextSibling.nextSibling.tagName == 'DL' ) {

// looks like we have found {{la|...}}

laNode = parentNode.nextSibling.nextSibling.nextSibling.nextSibling;

}

if (laNode) {

if (laNode.childNodes[1].tagName == 'DD') {

var viewAfdNode = laNode.childNodes[1].lastChild.previousSibling;

if (viewAfdNode) {

if (viewAfdNode.textContent == 'View AfD' &&

viewAfdNode.previousSibling) {

viewAfdNode.previousSibling.nodeValue = ' — (Afd: ';

viewAfdNode.firstChild.nodeValue = 'View';

var delsortAfdNode = viewAfdNode.cloneNode(true);

delsortAfdNode.firstChild.nodeValue = 'Delsort';

delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');

delsortAfdNode = viewAfdNode.parentNode.insertBefore( delsortAfdNode, viewAfdNode.parentNode.lastChild );

viewAfdNode.parentNode.insertBefore( document.createTextNode ( ' | ' ), delsortAfdNode );

}

else {

var delsortAfdNode = document.createElement('A');

delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');

delsortAfdNode.innerHTML = 'Delsort';

laNode.appendChild ( document.createTextNode ( ' - ' ) );

laNode.appendChild ( delsortAfdNode );

}

}

}

}

else {

// Delsort.debug ('Skipping nomination "' + window['wgAfdPage'] + '"; expected preamble not present.');

var delsortAfdNode = document.createElement('A');

delsortAfdNode.setAttribute('href', 'javascript:showDelsortFrame("' + wgAfdPage + '")');

delsortAfdNode.innerHTML = 'Delsort';

parentNode.parentNode.insertBefore ( document.createTextNode ( ' - ' ), parentNode.nextSibling );

parentNode.parentNode.insertBefore ( delsortAfdNode , parentNode.nextSibling );

}

}

else {

Delsort.debug ('Skipping headline "' + spans[i].textContent + '"');

}

}

}

}

Delsort.status = function( text ) {

return new Status( text, 'Status', 'status' );

}

Delsort.info = function( text ) {

return new Status( text, 'Info', 'info' );

}

Delsort.warn = function( text ) {

return new Status( text, 'Warning', 'error' );

}

Delsort.error = function( text ) {

return new Status( text, 'Error', 'error' );

}

Delsort.progress = function( text ) {

// disable the "....." until I can work out how to

// achieve that again using the new TW framework

if ( text == '.' ) return;

return new Status( text, 'Progress', 'info' );

}

Delsort.debug = function( text ) {

if ( DelsortConfig['debugLevel'] > 0 ) {

return new Status( text, 'Debug', 'info' );

}

}

Delsort.init = function() {

add_opera_delsort_compact_css();

if ( typeof DelsortConfig.transcludeRE == 'undefined' )

DelsortConfig.transcludeRE = new RegExp('Wikipedia:Deletion today|Wikipedia:Articles for deletion\/Log\/');

if ( typeof ( WikiPage ) == 'function' ) {

// create wgWikiPage for the current page if it doesnt already exist

if (! window['wgWikiPage'] )

wgWikiPage = new WikiPage(null,wgPageName);

if ( DelsortConfig.transcludeRE.test ( wgWikiPage.page ) )

Delsort.add_inline_ui();

if ( wgWikiPage.superarticle == 'Articles for deletion' &&

wgWikiPage.subarticle.substr(0,3) != 'Log' ) {

window['wgAfdPage'] = wgPageName;

add_delsort_tab();

}

return;

}

if ( wgNamespaceNumber == 4 ) {

var subTitleRE = /^([^/]+)\/(.+)/;

if ( subTitleRE.exec ( wgTitle ) ) {

window['wgDirname'] = RegExp.$1;

window['wgSubTitle'] = RegExp.$2;

}

if (!window['wgDirname'] || !window['wgSubTitle'] || wgDirname != 'Articles for deletion') return;

window['wgAfdPage'] = wgPageName;

add_delsort_tab();

}

}

$(Delsort.init);

function showDelsortFrame(pAfdPage) {

if (pAfdPage)

window['wgAfdPage'] = pAfdPage;

// The frame contents are cached

if ( Delsort['PopupContents'] )

Delsort.displayPopup( Delsort.PopupContents, "Select deletion sorting criteria" );

else

Delsort.loadFrameContents();

}

Delsort.loadFrameContents = function () {

try {

delsortCompatList = sajax_init_object();

delsortCompatList.overrideMimeType('text/xml');

var query = {

'title': DelsortConfig.compactPage

};

delsortCompatList.onreadystatechange = showDelsortFrameCallback;

delsortCompatList.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );

delsortCompatList.send( null );

} catch(e) {

if( e instanceof Exception ) {

Delsort.error( 'Error: ' + e.what() );

} else {

Delsort.error( 'Error: ' + e );

}

}

}

function showDelsortFrameCallback() {

if ( delsortCompatList.readyState != 4 ){

return;

}

if( delsortCompatList.status != 200 ){

Delsort.error('Bad status , bailing out; status = ' + delsortCompatList.status );

return;

}

var doc = delsortCompatList.responseXML;

var list = doc.getElementById('bodyContent').cloneNode(true);

if(! list ) {

Delsort.error( 'Unable to get the list, aborting.');

return;

}

var currentNode = list.firstChild;

var node;

// remove the heading

do {

node = currentNode;

currentNode = node.nextSibling;

list.removeChild ( node );

} while (node.id != 'toc');

// remove the edit links

var spans = list.getElementsByTagName('span');

var i = 0;

for (i = 0; i < spans.length; i++) {

if (spans[i].className == 'editsection') {

spans[i].parentNode.removeChild ( spans[i] );

}

}

var delsortLinkRE = new RegExp ('\/wiki\/Wikipedia:WikiProject_Deletion_sorting\/(.*)');

// remove the edit links

var anchors = list.getElementsByTagName('a');

var i = 0;

for (i = 0; i < anchors.length; i++) {

if ( anchors[i].href && delsortLinkRE.exec(anchors[i].href) ) {

pType = RegExp.$1;

pType = pType.replace(/_/g,' ');

if( navigator.userAgent.indexOf("Opera") != -1 ) {

anchors[i].href = "#";

anchors[i].onclick = new Function("delsortArticle('" + pType + "')");

}

else {

anchors[i].href = "javascript:delsortArticle('" + pType + "')";

}

}

}

Delsort.PopupContents = list;

Delsort.displayPopup( list, "Select deletion sorting criteria" );

}

Delsort.displayPopup = function(pContent, pTitle) {

if ( DelsortConfig['debugLevel'] > 0 )

Status.debugLevel = DelsortConfig.debugLevel;

if (!window['delsortWindow']) {

delsortWindow = new SimpleWindow( 800, 400 );

}

if (pTitle)

delsortWindow.setTitle( pTitle )

if (pContent)

delsortWindow.setContent( pContent );

delsortWindow.display();

}

function delsortArticle( pType ) {

pType = unescape(pType);

window['twDelsortType'] = pType;

wgAfdPage = unescape(wgAfdPage).replace('_',' ','g');

Delsort.displayPopup ( null, "Performing deletion sorting" );

Status.init( window['delsortWindow'].content );

var subpageRE = new RegExp('Wikipedia:Articles for deletion\/(.*)');

if ( subpageRE.exec( wgAfdPage ) ) {

wgNominatedArticle = RegExp.$1;

}

else {

Delsort.error( 'Can not determine article name for "' + wgAfdPage + '", aborting');

return;

}

var additionalNominationRE = new RegExp(' ([(]([0-9]+..|[a-z]+) [Nn]omination[)])');

var pRegexResults = additionalNominationRE.exec( wgNominatedArticle );

wgNominationIndex = '';

if ( pRegexResults ) {

wgNominationIndex = pRegexResults[1];

wgNominatedArticle = wgNominatedArticle.substr(0, pRegexResults.index);

}

Delsort.status( 'Nominated article name: ' + wgNominatedArticle );

if (wgNominationIndex)

Delsort.status( 'Nomination index: ' + wgNominationIndex );

// check the article exists

try {

delsortXML = sajax_init_object();

Delsort.debug( 'delsortXML' + delsortXML );

delsortXML.overrideMimeType('text/xml');

var query = {

'action': 'query',

'titles': wgNominatedArticle,

'prop': 'info',

'format': 'xml'

};

Delsort.status( 'Check the article "' + wgNominatedArticle + '" exists ...');

delsortXML.onreadystatechange = Delsort.verifyArticleExistsCallback;

if (typeof (query.toSource) == 'undefined') {

Delsort.debug( 'query:' + query );

}

else {

Delsort.debug( 'query:' + query.toSource() );

}

var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?' + QueryString.create( query );

Delsort.debug( 'url:' + url );

delsortXML.open( 'GET' , url, true );

delsortXML.send( null );

} catch(e) {

if( e instanceof Exception ) {

Delsort.error( 'Error: ' + e.what() );

} else {

Delsort.error( 'Error: ' + e );

}

}

}

Delsort.verifyArticleExistsCallback = function() {

var doc = Delsort.getAJAXResponse();

if (typeof doc != 'object') return;

Delsort.debug( ' Article test responseXML = ' + delsortXML.responseText );

var pageNode = doc.getElementsByTagName('page');

if (!pageNode || !pageNode[0] || !pageNode[0].getAttribute('lastrevid')) {

Delsort.status( 'Article not found' );

return;

}

Delsort.status( ' OK ' );

try {

delsortXML = sajax_init_object();

Delsort.debug( 'delsortXML' + delsortXML );

delsortXML.overrideMimeType('text/xml');

var query = {

'action': 'submit',

'title': 'Wikipedia:WikiProject Deletion sorting/' + window['twDelsortType'],

'section': 1

};

Delsort.status( 'Grabbing edit form for ' + query.title);

delsortXML.onreadystatechange = delsortCallback;

Delsort.debug( 'query:' + query.toSource() );

delsortXML.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );

delsortXML.send( null );

} catch(e) {

if( e instanceof Exception ) {

Delsort.error( 'Error: ' + e.what() );

} else {

Delsort.error( 'Error: ' + e );

}

}

}

function delsortCallback() {

var delsortForm = Delsort.getAJAXEditForm();

if (typeof delsortForm != 'object') return;

var doc = delsortForm.ownerDocument;

var textbox = doc.getElementById( 'wpTextbox1' );

Delsort.status( 'Checking contents of ' + window['twDelsortType'] + ' list');

Delsort.debug( 'Looking for ' + wgNominatedArticle + ' in ' + textbox.value);

if ( (textbox.value.indexOf( wgNominatedArticle + '}}' ) != -1) ||

(textbox.value.indexOf( wgNominatedArticle.replace(/ /g,'_') + '}}' ) != -1) )

{

Delsort.error( wgNominatedArticle + ' already listed on ' + window['twDelsortType']);

return;

}

Delsort.progress( ': ok' );

// remove (U.S. State) and (country) after Georgia

var sectionHeaderTitle = window['twDelsortType'].replace(/ [(].*[)]/,'');

var sectionHeaderRE = new RegExp('(==+ *(.*[^=\n]*) *==+)\n(\n*<[^>]*>)*(\n)*');

if ( ! sectionHeaderRE.test( textbox.value ) ) {

Delsort.error( 'Unable to locate where to place the new listing; aborting.' );

return;

}

var sectionHeader = RegExp.$1;

Delsort.debug( 'Found section ' + sectionHeader );

var sectionHeaderAcceptRE = new RegExp('(List of deletion discussions|Articles for deletion|General|Other|' + sectionHeaderTitle + ')');

if ( ! sectionHeaderAcceptRE.test( sectionHeader ) ) {

Delsort.error( 'The section header title "' + sectionHeader + '" looks a bit odd; aborting.' );

return;

}

var newval = textbox.value.replace(sectionHeaderRE,'$&{{' + wgAfdPage + '}}\n');

if (textbox.value == newval) {

Delsort.error( 'Unable to add Afd, will abort.' );

return;

}

textbox.value = newval;

Delsort.debug('contents = ' + textbox.value);

Delsort.status( 'Updating the summary...' );

var summary = "Listing " + wgNominatedArticle + "";

if ( wgNominationIndex )

summary += wgNominationIndex;

Delsort.progress( summary );

// safety valve to prevent bad edit summaries

if ( summary.indexOf ( 'Log' ) > -1 ) {

Delsort.error ( 'incorrect summary, aborting' );

return;

}

doc.getElementById( 'wpSummary' ).value = summary; // + TwinkleConfig.summaryAd;

// Mark adding an article to a delsort list as a major edit

// to ensure it appears on Watchlists

doc.getElementById( 'wpMinoredit' ).checked = false;

if ( DelsortConfig['watchDelsortedLists'] > 0 ) {

Delsort.debug( ' (Watching the Delsort list) ' );

doc.getElementById( 'wpWatchthis' ).checked = true;

}

if ( DelsortConfig['watchDelsortedLists'] == 0 ) {

Delsort.debug( ' (Not watching the Delsort list) ' );

doc.getElementById( 'wpWatchthis' ).checked = false;

}

// debugging interrupt to prevent damage

// return;

if (! Delsort.submitHiddenForm ( delsortForm ) )

return;

Delsort.progress( 'done' );

// if the user was in edit mode, use the current form

if (typeof Delsort.afdForm == 'object' && Delsort.afdForm &&

Delsort.afdForm['tagName'] && Delsort.afdForm['tagName'] == 'FORM') {

Delsort.debug( ' Found that the Afd is already in edit mode... ' );

Delsort.markAfdDelsorted( Delsort.afdForm );

return;

}

Delsort.debug( ' Calling markDelsortedArticle()... ' );

markDelsortedArticle();

}

function markDelsortedArticle( pType ) {

if ( pType && !window['twDelsortType'])

window['twDelsortType'] = pType;

Delsort.debug( ' In markDelsortedArticle... ' );

try {

delsortXML = sajax_init_object();

Delsort.debug( 'delsortXML' + delsortXML );

delsortXML.overrideMimeType('text/xml');

var query = {

'action': 'submit',

'title': wgAfdPage

};

Delsort.status( 'Grabbing edit form for ' + query.title);

delsortXML.onreadystatechange = markDelsortedCallback;

Delsort.debug( 'query:' + query.toSource() );

delsortXML.open( 'GET' , mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?' + QueryString.create( query ), true );

delsortXML.send( null );

} catch(e) {

if( e instanceof Exception ) {

Delsort.error( 'Error: ' + e.what() );

} else {

Delsort.error( 'Error: ' + e );

}

}

}

function markDelsortedCallback() {

var afdForm = Delsort.getAJAXEditForm ();

if (typeof afdForm != 'object') return;

Delsort.markAfdDelsorted ( afdForm );

}

// returns 0 when still in progress

// -1 if there was an error

// or the edit form when successfully obtained

Delsort.getAJAXResponse = function() {

if ( delsortXML.readyState != 4 ){

Delsort.progress('.');

return 0;

}

if( delsortXML.status != 200 ){

Delsort.error('Bad status , bailing out; status = ' + delsortXML.status);

return -1;

}

var doc = delsortXML.responseXML;

if( !doc ) {

Delsort.error( 'Possible failure in receiving document, will abort.' );

return -1;

}

Delsort.progress( 'done' );

return doc;

}

Delsort.getAJAXEditForm = function() {

var doc = Delsort.getAJAXResponse();

if (typeof doc != 'object') return doc;

var editForm = doc.getElementById( 'editform' );

if(! editForm ) {

Delsort.error( 'Possible failure in receiving document, aborting.' + doc);

return -1;

}

return editForm;

}

Delsort.markAfdDelsorted = function( pAfdForm ) {

var textbox = pAfdForm['wpTextbox1'];

var modified = ( textbox.value == textbox.defaultValue ) ? 0 : 1;

// if the last character in the box is a sig, add a new link character

if (/[~]$/.test ( textbox.value ) )

textbox.value += "\n";

textbox.value += "{{subst:" + "delsort|" + window['twDelsortType'] + "}} -- ~~" + "~~";

Delsort.debug('contents = ' + textbox.value);

Delsort.status( 'Updating the summary...' );

// TODO: the " (xth nom)" needs to be stripped

var summary = "Listing on WP:DELSORT under " + window['twDelsortType'];

// preserve any manual comments in the edit summary

var wpSummaryNode = pAfdForm['wpSummary'];

if ( wpSummaryNode.value != wpSummaryNode.defaultValue )

wpSummaryNode.value += '; ' + summary;

else

wpSummaryNode.value = summary;

Delsort.progress( summary );

wpPreviewMode = document.getElementById("wikiPreview") ? 1 : 0;

// Marking article as delsorted is a minor edit

// unless the the Afd form is in preview mode or the user

// has manually changed the textbox

var wpMinoreditNode = pAfdForm['wpMinoredit'];

if ( wpMinoreditNode.checked == false &&

!wpPreviewMode && !modified )

wpMinoreditNode.checked = true;

if ( DelsortConfig['watchDelsortedAfd'] > 0 ) {

Delsort.debug( ' (Watching the Afd) ' );

pAfdForm['wpWatchthis'].checked = true;

}

if ( DelsortConfig['watchDelsortedAfd'] == 0 ) {

Delsort.debug( ' (Not watching the Afd) ' );

pAfdForm['wpWatchthis'].checked = false;

}

// when the Afd has been trancluded onto the currently displayed

// page (i.e. the logs), the form submission happens in the background

if ( unescape(wgPageName).replace('_',' ','g') != wgAfdPage ) {

Delsort.submitHiddenForm(pAfdForm);

if (window['delsortWindow'] && window['delsortWindow']['frame'] ) {

try {

document.body.removeChild( window['delsortWindow'].frame );

} catch (x) {}

}

return;

}

// if the form was in edit mode, there is no need to add the from to

// the document before submission.

if (! Delsort.afdForm ) {

Delsort.debug( ' appending the form to the document ' );

document.body.appendChild( pAfdForm );

}

Delsort.status( 'Submitting the form...' );

pAfdForm.submit();

}

Delsort.getIFrame = function() {

var iFrameID = 'delsortFrame';

var iFrame = document.getElementById('delsortFrame');

if (iFrame) {

iFrame.setAttribute('src', 'about:blank');

return iFrame;

}

iFrame = document.createElement('IFRAME');

if(! iFrame ) {

Delsort.error( 'Unable to create an IFRAME, aborting.');

return;

}

iFrame.setAttribute('src', 'about:blank');

iFrame.setAttribute('id', iFrameID);

iFrame.setAttribute('NAME', iFrameID);

iFrame.style.display = 'none';

iFrame.style.width = 0;

iFrame.style.height = 0;

document.body.appendChild( iFrame );

return iFrame;

}

Delsort.submitHiddenForm = function(pForm) {

iFrame = Delsort.getIFrame();

pForm.target = iFrame.id;

iFrame.appendChild( pForm);

Delsort.status( 'Submitting the form...' );

try {

pForm.submit();

} catch(e) {

if( e instanceof Exception ) {

Delsort.error( 'Error: ' + e.what() );

} else {

Delsort.error( 'Error: ' + e );

}

return false;

}

return true;

}

//