MediaWiki:Gadget-RequestDeletion.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/***************************************************
 * Adds a small link to the top of the page of     *
 * each item with a link for quickly requesting a  *
 * deletion on [[Wikidata:Requests for deletion]]. *
 * Author: [[User:Bene*]]                          *
 ***************************************************/

//<nowiki>
( function ( mw, $ ) {
	var i18nData = require( './RequestDeletion-i18n.json' );
	i18nData.no = i18nData.nb;

	// set Language
	var lang = mw.user.options.get( 'language' );
	if ( !( lang in i18nData ) ) {
		lang = 'en';
	}

	// set Entity-Id
	var entityId = mw.config.get( 'wbEntityId' );
	if ( !entityId ) {
		return;
	}
	var entityNamespace = '', title = 'Wikidata:Requests for deletions';
	if ( entityId.substr( 0, 1 ) === 'P' ) {
		entityNamespace = 'Property:';
		title = 'Wikidata:Properties for deletion';
	} else if ( entityId.substr( 0, 1 ) === 'L' ) {
		entityNamespace = 'Lexeme:';
	}

	// if already requested
	var requested = false;

	/**
	 * Return the localized version of a message.
	 */
	function i18n( key ) {
		if ( i18nData[ lang ][ key ] ) {
			return i18nData[ lang ][ key ];
		}
		return i18nData.en[ key ];
	}

	/**
	 * Checks whether the item is requested for deletion yet.
	 */
	function check() {
		var api = new mw.Api();
		api.get( {
			action: 'query',
			titles: title,
			prop: 'links',
			pltitles: entityNamespace + '' + entityId,
			formatversion: 2,
		} )
		.then( function ( data ) {
			if ( data.error ) {
				return;
			}
			if ( !data.query.pages[ 0 ].links ) {
				return;
			}
			api.get( {
				action: 'query',
				prop: 'revisions',
				formatversion: 2,
				rvprop: 'content',
				rvslots: 'main',
				rvlimit: 1,
				titles: title,
			} )
			.then( function ( data ) {
				if ( data.error ) {
					return;
				}
				var regex = '==\\s*\\[\\[([Ll]exeme:|[Pp]roperty:)?[LlPpQq]' + entityId.substr( 1 ) + '\\]\\]\\s*==';
				regex += '|==\\s*{{PfD\\|' + entityId.substr( 1 ) + '}}\\s*==';
				regex += '|{{Rfd group/[0-9]+(\\|(\\s*([Ll]exeme:|[Pp]roperty:)?[LlPpQq][0-9]+\\s*)?)*\\|\\s*([Ll]exeme:|[Pp]roperty:)?[LlPpQq]' + entityId.substr( 1 ) + '\\s*\\|((\\s*([Ll]exeme:|[Pp]roperty:)?[LlPpQq][0-9]+\\s*)?\\|)*.*}}';
				if ( data.query.pages[ 0 ].revisions[ 0 ].slots.main.content.match( new RegExp( regex, 'g' ) ) !== null ) {
					mw.notify(
						i18n( 'requested' ),
						{
							autoHide: false,
							title: 'deletionRequest.js',
							tag: 'deletionRequest-exist'
						}
					);
					$( '#content' ).prepend(
						$( '<span>' )
						.css( {
							float: 'right',
							'z-index': 10001,
							position: 'relative',
							top: '4px',
							right: '6px'
						} )
						.attr( 'id', 'requestdeletion-requested' )
						.append(
							$( '<a>' )
							.attr( 'href', mw.util.getUrl( title ) + '#' + entityNamespace + '' + entityId )
							.append(
								$( '<img>' )
								.attr( {
									src: '//upload.wikimedia.org/wikipedia/commons/thumb/1/17/Warning.svg/25px-Warning.svg.png',
									title: i18n( 'requested' )
								} )
							)
						)
					);
					requested = true;
				}
			} );
		} );
	}

	/**
	 * Add link to top of page.
	 */
	function init() {
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util', 'jquery.ui' ] )
		.then( function () {
			check();
			$( '<div>' )
			.attr( 'id', 'requestdeletion' )
			.append(
				$( '<form>' )
				.attr( 'id', 'requestdeletion-form' )
				.submit( requestDeletion )
				.append(
					$( '<p>' )
					.text( i18n( 'notice' ) )
				) // </p>
				.append(
					$( '<fieldset>' )
					.append(
						$( '<legend>' )
						.text( i18n( 'description' ) )
					) // </legend>
					.append(
						$( '<p>' )
						.append(
							$( '<label>' )
							.attr( 'for', 'requestdeletion-reason' )
							.text( i18n( 'reason' ) )
						) // </label>
						.append(
							$( '<input>' )
							.attr( {
								'type': 'text',
								'id': 'requestdeletion-reason'
							} )
						) // </input>
					) // </p>
				)
			) // </form>
			.append(
				$( '<p>' )
				.attr( 'id', 'requestdeletion-result' )
			) // </p>
			.appendTo( '#content' )
			.dialog( {
				title: i18n( 'title' ),
				autoOpen: false,
				modal: true,
				width: 500,
				buttons: [ {
					id: 'requestdeletion-button-request',
					text: i18n( 'title' ),
					click: requestDeletion
				}, {
					id: 'requestdeletion-button-close',
					text: i18n( 'close' ),
					click: function () {
						$( '#requestdeletion' ).dialog( 'close' );
					}
				} ]
			} );
			var portletLink = mw.util.addPortletLink(
				'p-cactions',
				'#',
				i18n( 'title' ),
				'ca-requestdeletion',
				i18n( 'description' ),
				null,
				'#ca-requestdeletion'
			);
			$( portletLink ).click( function ( e ) {
				e.preventDefault();
				$( '#requestdeletion-result' ).html( '' );
				$( '#requestdeletion' ).dialog( 'open' );
			} );
		} );
	}

	function requestDeletion( event ) {
		var reason = $( '#requestdeletion-reason' ).val();
		if ( requested ) {
			showError( 'requested' );
			requested = false; // can retry
		}
		else if ( reason === '' ) {
			showError( 'reason' );
		}
		else {
			addRequest(
				mw.util.wikiUrlencode( entityId ),
				function () {
					$( '#requestdeletion' ).dialog( 'close' );
					mw.notify( i18n( 'success' ) );
				},
				reason
			);
		}
		event.preventDefault();
	}

	function showSpinner() {
		$( '#requestdeletion-result' ).html( '<div id="requestdeletion-spinner" />' );
		$.createSpinner( {
			size: 'large',
			type: 'block',
			id: 'requestdeletion-spinner'
		} ).replaceAll( '#requestdeletion-spinner' );
	}

	function showError( err, p1 ) {
		$( '#requestdeletion-result' ).html(
			$( '<p>' )
			.attr( 'class', 'error' )
			.text( i18n( 'error-' + err ).replace( '$1', p1 ) )
		);
	}

	/**
	 * Add new error request.
	 * @param item item to delete
	 * @param success function called on success
	 * @param reason reason for deletion
	 */
	function addRequest( entity, success, reason ) {
		showSpinner();
		// Regex to change "Q####" into "[[Q####]]"
		reason = ' ' + reason;
		reason = reason.replace( /[ ]([Qq][0-9]+)/g, ' [[$1]]' );
		reason = reason.replace( /[ ]([Ll]exeme:[Ll][0-9]+|[Pp]roperty:[Pp][0-9]+)/g, ' [[$1]]' );
		reason = reason.replace( /[ ]([Ll][0-9]+)/g, ' [[Lexeme:$1]]' );
		reason = reason.replace( /[ ]([Pp][0-9]+)/g, ' [[Property:$1]]' );
		// removing too too much spaces
		if ( reason.charAt( 0 ) === ' ' ) {
			reason = reason.substr( 1 );
		}
		var entityId = entityNamespace + '' + entity,
			api = new mw.Api();

		api.get( {
			action: 'query',
			prop: 'revisions',
			titles: entityId,
			formatversion: 2,
			rvprop: [ 'user', 'userid' ],
			rvlimit: 1,
			rvdir: 'newer',
		} )
		.then( function ( data ) {
			var pg = data.query.pages[0];
			if ( pg.revisions && pg.revisions[0].userid !== 0 ) {
				return pg.revisions[0].user;
			} else {
				return null;
			}
		} )
		.then( function ( username ) {
			var summary = '/* ' + entityId + ' */ requested deletion';
			if ( username && username !== mw.config.get( 'wgUserName' ) ) {
				summary += ', created by [[User:' + username + ']]';
			}
			summary += ' ([[MediaWiki talk:Gadget-RequestDeletion.js|RD]])';
			return api.postWithEditToken( {
				action: 'edit',
				title: title,
				watchlist: 'nochange',
				section: 'new',
				summary: summary,
				sectiontitle: '[[' + entityId + ']]',
				text: '{{subst:Request for deletion|itemid=' + entityId + '|reason=' + reason + '|header=no}}' + ( reason.indexOf( '~~~~' ) === -1 ? ' ~~~~' : '' ) + '\n',
			} );
		} )
		.then( function ( data ) {
			if ( data.error && data.error.info ) {
				showError( 'api', data.error.info );
			} else {
				success();
			}
		}, function ( jqXHR, textStatus, errorThrown ) {
			showError( 'api', textStatus );
		} );
	}

	$( init );
}( mediaWiki, jQuery ) );
//</nowiki>