Jump to content

User:Beetstra/twinklespeedy.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
// If TwinkleConfig aint exist.
if( typeof( TwinkleConfig ) == 'undefined' ) {
	TwinkleConfig = function() {};
}

/**
TwinkleConfig.addAdToSummary
If [[WP:TWINKLE|TWINKLE]] should be added or not to summary
*/
if( typeof( TwinkleConfig.addAdToSummary ) == 'undefined' ) {
	TwinkleConfig.addAdToSummary = true;
}

/**
TwinkleConfig.addAdToDeletionSummary
If [[WP:TWINKLE|TWINKLE]] should be added or not to the deletion summary (admin only)
*/
if( typeof( TwinkleConfig.addAdToDeletionSummary ) == 'undefined' ) {
	TwinkleConfig.addAdToDeletionSummary = true;
}

/**
TwinkleConfig.watchSpeedyPages (array)
What types of actions that should result in forced addition to watchlist
*/
if( typeof( TwinkleConfig.watchSpeedyPages ) == 'undefined' ) {
	TwinkleConfig.watchSpeedyPages = [ 'g3', 'g5', 'g10', 'g11', 'g12' ];
}

/**
TwinkleConfig.deleteTalkPageOnDelete
If talk page if exists should also be deleted (CSD G8) when spedying a page (admin only)
*/
if( typeof( TwinkleConfig.deleteTalkPageOnDelete ) == 'undefined' ) {
	TwinkleConfig.deleteTalkPageOnDelete = false;
}

function twinkleSpeedyDelete() {
	if( wgNamespaceNumber < 0 || wgCurRevisionId == false ) {
		return;
	}
	if( userIsInGroup( 'sysop' ) ) {
		mw.util.addPortletLink('p-cactions', "javascript:twinklespeedy( 'csd' )", "db (csd)", "ca-db0", "Speedy delete according to WP:CSD", "");
		mw.util.addPortletLink('p-cactions', "javascript:twinklespeedy( 'reason' )", "db (reason)", "ca-db0", "Speedy deletion with reason", "");
	} else {
		mw.util.addPortletLink('p-cactions', "javascript:twinklespeedy( 'csd' )", "db (csd)", "ca-db0", "Request speedy deletion according to WP:CSD", "");
		mw.util.addPortletLink('p-cactions', "javascript:twinklespeedy( 'reason' )", "db (reason)", "ca-db0", "Request speedy deletion with reason", "");
	}	
}
$(twinkleSpeedyDelete);

function twinklespeedy( type ) {
	twinklespeedy.type = type;
	switch( type ) {
		case 'csd':
		twinklespeedy.Window = new SimpleWindow( 800, 400 );
		twinklespeedy.Window.setTitle( "Choose criteria for speedy deletion" );

		function createOption( value, text ) {
			var div = document.createElement( 'div' );
			var input = document.createElement( 'input' );
			input.value = value;
			input.name = 'csd';
			input.id = 'wp' + value;
			input.type = 'radio';
			var label = document.createElement( 'label' );
			label.setAttribute( 'for', value );
			label.appendChild( document.createTextNode( text ) );
			div.appendChild( input );
			div.appendChild( label );

			return div;
		}
		var form = document.createElement( 'form' );
		form.addEventListener( 'change', twinklespeedy.csd, true );
		form.appendChild( createOption( 'nonsense', 'G1: Patent nonsense.' ) );
		form.appendChild( createOption( 'test', 'G2: Test page.' ) );
		form.appendChild( createOption( 'vandalism', 'G3: Vandalism.' ) );
		form.appendChild( createOption( 'pagemove', 'G3: Nonsense redirects that are created from the cleanup of page move vandalism.' ) );
		form.appendChild( createOption( 'repost', 'G4: Copies of material that was previously deleted after an XfD discussion.' ) );
		form.appendChild( createOption( 'banned', 'G5: Contributions made by a banned user.' ) );
		form.appendChild( createOption( 'histmerge', 'G6: History merge.' ) );
		form.appendChild( createOption( 'move', 'G6: Making way for a noncontroversial move.' ) );
		form.appendChild( createOption( 'afd', 'G6: An admin has closed an Articles for deletion debate as a "delete".' ) );
		form.appendChild( createOption( 'g6', 'G6: Other non-controversial "housekeeping" tasks' ) );
		form.appendChild( createOption( 'author', 'G7: Speedy request by only editor.' ) );
		form.appendChild( createOption( 'blanked', 'G7: Page blanked by only editor.' ) );
		form.appendChild( createOption( 'talk', 'G8: Talk page of a deleted or nonexistent page.' ) );
		form.appendChild( createOption( 'attack', 'G10: Attack page intended to disparage its subject.' ) );
		form.appendChild( createOption( 'spam', 'G11: Pages that exist only to promote a company, product, or service.' ) );
		form.appendChild( createOption( 'copyvio', 'G12: Blatant copyright violation.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'nocontext', 'A1: Very short articles without context.' ) );
		form.appendChild( createOption( 'foreign', 'A2: Foreign language article duplicated on other Wikimedia project.' ) );
		form.appendChild( createOption( 'nocontent', 'A3: No content other than external links of whatever kind, or an attempt to contact subject of article.' ) );
		form.appendChild( createOption( 'transwiki', 'A5: Transwikification completed.' ) );
		form.appendChild( createOption( 'bio', 'A7: Non-notable biography / article about a person, group, company, or website that does not assert the notability of the subject.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'redirnone', 'R1: Redirect to non-existent page.' ) );
		form.appendChild( createOption( 'rediruser', 'R2: Redirect to user page.' ) );
		form.appendChild( createOption( 'redirtypo', 'R3: Redirect that is a result of an implausible typo.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'redundantimage', 'I1: Same or better image exists on Wikipedia (not for now on Commons).' ) );
		form.appendChild( createOption( 'noimage', 'I2: Corrupt or empty image.' ) );
		form.appendChild( createOption( 'noncom', 'I3: "No commercial use" or "by permission" images uploaded after target date.' ) );
		form.appendChild( createOption( 'unksource', 'I4: Lack of licensing.' ) );
		form.appendChild( createOption( 'unfree', 'I5: Unused copyright image.' ) );
		form.appendChild( createOption( 'norat', 'I6: Image with fair use tag but no fair use rationale.' ) );
		form.appendChild( createOption( 'badfairuse', 'I7: Bad fair use rationale - image tagged for fair use under a rationale that is patently irrelevant to the actual image.' ) );
		form.appendChild( createOption( 'nowcommons', 'I8: Images available as bit-for-bit identical copies on the Wikimedia Commons,' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'catempty', 'C1: Category that is empty for at least four days and has never contained anything other than links to parent categories.' ) );
		form.appendChild( createOption( 'catfd', 'C3: Category that is used solely by a template that has been deleted.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'userreq', 'U1: User\'s subpage requested to be deleted by the user with whom it is associated.' ) );
		form.appendChild( createOption( 'nouser', 'U2: Userpages of users who do not exist.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'disparage', 'T1: Templates that are divisive and inflammatory.' ) );
		form.appendChild( document.createElement( 'hr' ) );
		form.appendChild( createOption( 'emptyportal', 'P2: Underpopulated portal.' ) );


		twinklespeedy.Window.setContent( form );
		twinklespeedy.Window.display();

		break;
		case 'reason':
		var criteria = prompt( "Enter reason for speedy deletion" );
		if( !criteria ) {
			return; // User abort action
		}
		if( userIsInGroup( 'sysop' ) ) {
			twinklespeedy.summary = "Speedy deletion, with reason: " + criteria + "." + ( TwinkleConfig.addAdToDeletionSummary ? ' [[WP:TWINKLE|TWINKLE]].' : '');
		} else {
			twinklespeedy.summary = "Requesting speedy deletion." + ( TwinkleConfig.addAdToSummary ? ' [[WP:TWINKLE|TWINKLE]]' : '');
		}
		twinklespeedy.code = "{{d" + "b" + ( criteria ? '|' + criteria : '' ) + "}}";
		Status.init( document.getElementById('bodyContent') );

		Status.status( 'Grabbing page' );

		editXML = sajax_init_object();
		editXML.overrideMimeType('text/xml');
		if( userIsInGroup( 'sysop' ) ) {
			editXML.open( 'GET' , wgServer + wgScriptPath + '/index.php?' + QueryString.create( { 'title': wgPageName, 'action': 'delete' } ), true);
		} else {
			editXML.open( 'GET' , wgServer + wgScriptPath + '/index.php?' + QueryString.create( { 'title': wgPageName, 'action': 'submit' } ), true);
		}
		editXML.onreadystatechange = twinklespeedyCallback;
		editXML.send( null );
		break;
	}
}
twinklespeedy.csd = function(e) {
	var convarr = {
		'nonsense': 'g1',
		'test': 'g2',
		'vandalism': 'g3',
		'pagemove': 'g3',
		'repost': 'g4',
		'banned': 'g5',
		'histmerge': 'g6',
		'move': 'g6',
		'afd': 'g6',
		'g6': 'g6',
		'author': 'g7',
		'blanked': 'g7',
		'talk': 'g8',
		'attack': 'g10',
		'spam': 'g11',
		'copyvio': 'g12',
		'nocontext': 'a1',
		'foreign': 'a2',
		'nocontent': 'a3', 
		'transwiki': 'a5',
		'bio': 'a7',
		'redirnone': 'r1',
		'rediruser': 'r2',
		'redirtypo': 'r3',
		'redundantimage': 'i1',
		'noimage': 'i2',
		'noncom': 'i3',
		'unksource': 'i4',
		'unfree': 'i5',
		'norat': 'i6',
		'badfairuse': 'i7',
		'nowcommons': 'i8',
		'catempty': 'c1',
		'catfd': 'c3',
		'userreq': 'u1',
		'nouser': 'u2',
		'disparage': 't1',
		'emptyportal': 'p2'
	};
	var reasarr = {
		'nonsense': 'was patent nonsense',
		'test': 'was a test page',
		'vandalism': 'was pure vandalism',
		'pagemove': 'was a nonsense redirect that where created as a byproduct after a cleanup of pagemove',
		'repost': 'was a copy of material previously deleted per XfD',
		'banned': 'was a contribution was made by a banned user',
		'histmerge': 'merging of history',
		'move': 'making way for a non-controversial move',
		'afd': 'deleting page per result of AfD',
		'g6': 'non-controversial housekeeping',
		'author': 'only editor requested deletion',
		'blanked': 'only editor has blanked the page',
		'talk': 'was a talk page of deleted or nonexistent page',
		'attack': 'was a attack page intented to disparage it\'s subject',
		'spam': 'page existed only to promote',
		'copyvio': 'was a blatant copyright violation',
		'nocontext': 'was a very short article without context',
		'foreign': 'was a foreign language page',
		'nocontent': 'had no content except for eventual external links or contact information', 
		'transwiki': 'completed transwikification',
		'bio': 'was a non-notable biography / article about a person, group, company, or website that does not assert the notability of the subject',
		'redirnone': 'was a redirect to an non-existent page',
		'rediruser': 'was a redirect to an user',
		'redirtypo': 'was a redirect based on an implausible typo',
		'redundantimage': 'same or better image exists on Wikipedia',
		'noimage': 'was a corrupt or empty image',
		'noncom': 'was an image with non-comercial use only restriction and uploaded after target date',
		'unksource': 'was an image lacking sources',
		'unfree': 'an unfree image that hasn\'t been used for more than seven days',
		'norat': 'was an image with fair use tag but no fair use rationale',
		'badfairuse': 'was an image with bad fair use rationale',
		'nowcommons': 'was an image that an bit-to-bit copy exists on wikimedia commons',
		'catempty': 'was an empty category',
		'catfd': 'was an category with sole purpouse been used by a now deleted template',
		'userreq': 'was a userpage, and it\'s user requested deletion',
		'nouser': 'was a userpage without any user',
		'disparage': 'was an divisive and inflammatory template',
		'emptyportal': 'was an underpopulated portal'
	};

	var value = e.target.value;
	var normalized = convarr[ value ];
	twinklespeedy.watch = TwinkleConfig.watchSpeedyPages.indexOf( normalized ) != -1;
	var reason = reasarr[ value ];
	if( userIsInGroup( 'sysop' ) ) {
		twinklespeedy.summary = "Speedy deleted per ([[WP:CSD#" + normalized + "|CSD " + normalized + "]]), " + reason + "." + ( TwinkleConfig.addAdToDeletionSummary ? ' [[WP:TWINKLE|TWINKLE]]' : '');
	} else {
		twinklespeedy.summary = "Requesting speedy deletion ([[WP:CSD#" + normalized + "|CSD " + normalized + "]])." + ( TwinkleConfig.addAdToSummary ? ' [[WP:TWINKLE|TWINKLE]]' : '');
		switch( normalized ) {
			case 'i8':
			var date = new Date();
			twinklespeedy.code = "{{" + "NowCommons" + "|month=" + date.getUTCMonthName() + "|day=" + date.getUTCDate() + "|year=" + date.getUTCFullYear() + "|1=" + wgPageName.replace( '_', ' ' ) + "}}";
			break;
			case 'g12':
			url = prompt( 'please enter url if available, including the http://' );
			if( url == null ) {
				return;
			}
			twinklespeedy.code = "{{d" + "b-" +  value + "|url=" + url + "}}";
			break;
			case 'i1':
			img = prompt( 'enter the image this is redundant to, excluding the Image: prefix' );
			if( img == null ) {
				return;
			}
			twinklespeedy.code = "{{d" + "b-" +  value + "|1=" + img + "}}";
			break;
			default:
			twinklespeedy.code = "{{d" + "b-" +  value + "}}";
			break;
		}
	}
	twinklespeedy.Window.close();
	Status.init( document.getElementById('bodyContent') );

	Status.status( 'Grabbing page' );

	editXML = sajax_init_object();
	editXML.overrideMimeType('text/xml');

	if( userIsInGroup( 'sysop' ) ) {
		editXML.open( 'GET' , wgServer + wgScriptPath + '/index.php?' + QueryString.create( { 'title': wgPageName, 'action': 'delete' } ), true);
	} else {
		editXML.open( 'GET' , wgServer + wgScriptPath + '/index.php?' + QueryString.create( { 'title': wgPageName, 'action': 'submit' } ), true);
	}
	editXML.onreadystatechange = twinklespeedyCallback;
	editXML.send( null );
}


function twinklespeedyCallback() {
	if ( editXML.readyState != 4 ){
		Status.progress('.');		
		return;
	} 

	if( editXML.status != 200 ){
		Status.error('Bad status , bailing out');		
		return;
	}

	Status.progress(' Done');

	// when we grabbed the page, it wasn't there
	if( editXML.responseText.indexOf( 'var wgCurRevisionId = false;' ) != -1 ) {
		Status.error( "It seems that the page doesn't exists, perhaps it has already been deleted'" );
		return;
	}

	var doc = editXML.responseXML;
	var form;

	if( userIsInGroup( 'sysop' ) ) {
		Status.status( 'Deleting page...' );

		form = doc.getElementById( 'deleteconfirm' );
		form.style.display = 'none';

		doc.getElementById( 'wpReason' ).value = twinklespeedy.summary;
		if( twinklespeedy.watch ) {
			doc.getElementById( 'wpWatch' ).checked = true;
		}

		if( TwinkleConfig.deleteTalkPageOnDelete && wgNamespaceNumber % 2 == 0 && document.getElementById( 'ca-talk' ).className != 'new' ) {
			var talk_page = namespaces[ wgNamespaceNumber  + 1 ] + ':' + wgTitle;
			var query = {
				'title': talk_page,
				'action': 'delete'
			};
			var win_ref = window.open(  wgServer + wgScriptPath + '/index.php?' + QueryString.create( query ), 'talkpage' , 'scrollbars=yes,width=800,height=400' );
			win_ref.watch = twinklespeedy.watch;
			win_ref.ad = TwinkleConfig.addAdToDeletionSummary;
			win_ref.onload = function() {
				if( this.watch ) {
					this.document.getElementById( 'wpWatch' ).checked = true;
				}
				this.document.getElementById( 'wpReason' ).value = "Speedy deleted per ([[WP:CSD#g8|CSD g8]]), was a talk page of deleted page." + ( this.ad ? ' [[WP:TWINKLE|TWINKLE]]' : '');
				this.document.getElementById( 'deleteconfirm' ).submit();
			}
			win_ref.onsubmit = function() { this.onload = function() { this.close() } };
		}
	} else {

		form = doc.getElementById( 'editform' );
		form.style.display = 'none';

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

		var text = textbox.value;

		Status.status( 'Checking for tags on the page...' );

		var tag = /(\{\{(?:db-?|delete)\|?.*?\}\})/.exec( text );

		if( tag ) {
			Status.warn( [ htmlNode( 'strong', tag[0] ) , " is alread placed on the page." ] )
			return;
		}

		var xfd = /(\{\{(?:[aitcm]fd|md1)[^{}]*?\}\})/i.exec( text );

		if( xfd && !confirm( "The deletion related template " + xfd[0] + " is already present on the page, do you still want to revert?" ) ) {
			return;
		}

		Status.progress(' Done');

		Status.status( 'Submitting form...' );

		textbox.value = twinklespeedy.code + "\n" + textbox.value;
		doc.getElementById( 'wpSummary' ).value = twinklespeedy.summary;	
		doc.getElementById( 'wpMinoredit' ).checked = true;
		if( twinklespeedy.watch ) {
			doc.getElementById( 'wpWatchthis' ).checked = true;
		}

	}
	document.getElementById('globalWrapper').appendChild( form );
	form.submit();	

	Status.progress(' Done');
}
// </nowiki>