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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// <nowiki> /**  * Rename Wizard Tools  * @author CSteipp, 2013  */ /*jshint undef:true, unused:true, quotmark:"single", trailing:true, browser:true */ /*global mediaWiki, jQuery, alert */ (function (mw, $) {  var phrases = { 	'current-info-anonymous': 'Login to view, or enter a name below', 	'input-username': 'Username: ', 	'input-username-from': 'Merge from (old username): ', 	'input-username-to': 'Merge to (new username): ', 	'input-wikilist': 'On Wikis: ', 	'merge-status-notavailable': 'Global Name is Taken', 	'merge-status-merged': 'Your Account is Merged', 	'info-status': 'Status: ', 	'info-gid': 'Global Id: ', 	'info-date': 'Merge Date: ', 	'info-homewiki': 'Home Wiki: ', 	'mergestatus-dne': 'User does not exist', 	'mergestatus-attached': 'Attached', 	'mergestatus-unattached': 'Unattached', 	'result-label-username': 'Result for Username: ', 	'result-label-confirmpost': 'Your request will be submitted as follows', 	'result-label-status-ok': 'Request Submitted', 	'result-label-status-error': 'There was an error submitting your request', 	'result-username-available': 'This name is available!', 	'result-username-unavailable': 'Sorry, this name is already taken.', 	'result-username-nonexist': '(no matching global name)', 	'action-link-createaccount': 'Create Account Now', 	'action-link-confirm': 'Confirm', 	'action-link-request': 'Make Request', 	'label-section-rename': 'Request Rename', 	'req-text-title': 'Request for Rename', 	'req-text-user': 'User "', 	'req-text-action1': '" is requesting that username "', 	'req-text-action2': '" is renamed and merged with the username "', 	'req-text-wikilist': '"' }; var templates = { 	'icon-ok': '<img src="//upload.wikimedia.org/wikipedia/commons/thumb/a/ac/Approve_icon.svg/30px-Approve_icon.svg.png"></img>', 	'icon-bad': '<img src="//upload.wikimedia.org/wikipedia/commons/thumb/4/42/Stop_x_nuvola.svg/30px-Stop_x_nuvola.svg.png"></img>', 	'icon-loading': '<div style="text-align: center"><img alt="saving report" src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif"></img></div>' };  function showStatus( $div, message ) { 	$div.empty().append( $('<h3>').text( message ) ); }  var gRW = { 	requestFromName: '', 	requestToName: '', 	requestWikis: {}, 	requestText: '',  	allWikis: { 		'enwikivoyage': 'en.wikivoyage.org', 		'dewikivoyage': 'de.wikivoyage.org', 		'itwikivoyage': 'it.wikivoyage.org', 		'frwikivoyage': 'fr.wikivoyage.org', 		'svwikivoyage': 'sv.wikivoyage.org', 		'nlwikivoyage': 'nl.wikivoyage.org', 		'ruwikivoyage': 'ru.wikivoyage.org' 	},  	setupCurrentInfo: function ( $infobox ) { 		if ( mw.user.isAnon() ) { 			$infobox 				.empty() 				.append( $('<p>').text( phrases['current-info-anonymous'] ) ); 		} else { 			this.getGlobalInfo( mw.user.getName(), $infobox, this.fillGlobalInfo ); 		} 	},   	fillGlobalInfo: function ( $infobox, username, guid, regDate, homeWiki, attachedWikis, unatachedWikis ) { 		var currentSite = mw.config.get( 'wgSiteName' ); 		var attachedMsg = '';  		$infobox.empty().append( $('<h3>').text( phrases['input-username'] + username ) );   		if ( guid !== 0 ) { 			if ( attachedWikis[currentSite] === undefined ) { 				// Global account exists, but is not attached here so we assume this user cannot use it 				attachedMsg = phrases['merge-status-notavailable']; 			} else { 				// Global account exists, and it's attached here, so we assume it belongs to this user 				attachedMsg = phrases['merge-status-merged']; 			}  			var $userdata = $('<ul>') 				.append( $('<li>').text( phrases['info-status'] + attachedMsg ) ) 				.append( $('<li>').text( phrases['info-gid'] + guid ) ) 				.append( $('<li>').text( phrases['info-date'] + regDate ) ) 				//.append( $('<li>').text( phrases['info-homewiki'] + homeWiki ) ) 				; 			$infobox.append( $userdata );  			var currentWikiStatus = { 				'enwikivoyage': phrases['mergestatus-dne'], 				'dewikivoyage': phrases['mergestatus-dne'], 				'itwikivoyage': phrases['mergestatus-dne'], 				'svwikivoyage': phrases['mergestatus-dne'], 				'nlwikivoyage': phrases['mergestatus-dne'], 				'enwiki83': phrases['mergestatus-dne'], 				'dewiki83': phrases['mergestatus-dne'] 			};  			var allWikis = gRW.allWikis; 			var ndx;  			for ( ndx = 0; ndx < attachedWikis.length; ++ndx ) { 				currentWikiStatus[ attachedWikis[ndx].wiki ] = phrases['mergestatus-attached']; 			}  			for ( ndx = 0; ndx < unatachedWikis.length; ++ndx ) { 				currentWikiStatus[ unatachedWikis[ndx].wiki ] = phrases['mergestatus-unattached']; 			}  			var wikistatus = $('<ul>');  			for (var wiki in allWikis) { 				wikistatus.append( $('<li>').text( allWikis[wiki] + ': ' + currentWikiStatus[wiki] ) ); 			} 			$infobox.append( $('<p>').text('Wikis') ); 			$infobox.append( wikistatus ); 		} else { 			$infobox.append( $('<p>').text( phrases['result-username-nonexist'] ) ); 		}  	},  	showSearchResult: function ( $searchbox, username, guid ) { 		$searchbox.empty().append( $('<h3>').text( phrases['result-label-username'] + username ) );  		if ( guid === 0 ) {  			var createLink = $( '<a>' ) 			.attr( 'href', mw.config.get('wgScriptPath') + '/index.php?title=Special:UserLogin&type=signup&wpName=' + encodeURIComponent( username ) ) 			.text( phrases['action-link-createaccount'] );  			$searchbox 			.append( $( templates['icon-ok'] ) ) 			.append( $( '<p>' ).text( phrases['result-username-available'] ) ) 			.append( createLink );  		} else { 			$searchbox.append( $( templates['icon-bad'] ) ); 			$searchbox.append( $( '<p>' ).text( phrases['result-username-unavailable'] ) ); 		} 	},  	fillRequest: function ( $reqbox, username, guid, regDate, homeWiki, attachedWikis, unatachedWikis ) { 		gRW.requestFromName = username; 		gRW.requestWikis = unatachedWikis; 		gRW.requestText = gRW.createRequestText( username, gRW.requestToName, unatachedWikis );  		$reqbox.empty().append( $('<p>').text( phrases['result-label-confirmpost'] ) );  		var requestLines = gRW.requestText.split('\n');  		for ( var ndx = 0; ndx < requestLines.length; ++ndx ) { 			$reqbox.append( $('<p>').text( requestLines[ndx] ) ); 		}  		var $confLink = $( '<a>' ) 		.on('click', function () { 			$reqbox.html( templates['icon-loading'] );  			var reqLines = gRW.requestText.split('\n'); 			gRW.addNewSection( $reqbox, 'Wikivoyage_talk:User_account_migration', reqLines[0], reqLines.slice(1).join('\n'), mw.user.tokens.get( 'csrfToken' ) ); 		} ) 		.text( phrases['action-link-confirm'] );  		$reqbox.append( $confLink ); 	},  	createRequestText: function ( fromname, toname ) { 		var currUser = mw.user.getName(); 		return '== ' + phrases['req-text-title'] + ' "' + fromname + '" > "' + toname + '" ==\n' + 			phrases['req-text-user'] + currUser + 			phrases['req-text-action1'] + fromname + 			phrases['req-text-action2'] + toname + 			phrases['req-text-wikilist'] + ' ~~' + '~~' + 			'\n'; 	},  	/** 	 * Get data about the CentralAuth (global) user 	 */ 	getGlobalInfo: function ( username, $div, callback ) { 		$.ajax({ 			url: mw.util.wikiScript( 'api' ), 			data: { 				format: 'json', 				action: 'query', 				meta: 'globaluserinfo', 				guiuser: username, 				guiprop: 'merged|unattached' 			}, 			dataType: 'json', 			type: 'GET', 			success: function ( data ) { 				if ( data && data.query && data.query.globaluserinfo ) { 					var guid = 0; 					var regdate = ''; 					var homewiki = ''; 					var merged = false; 					var unattached = false;  					if ( data.query.globaluserinfo.missing === undefined ) { 						guid = data.query.globaluserinfo.id; 						regdate = data.query.globaluserinfo.registration; 						homewiki = data.query.globaluserinfo.home; 						merged = data.query.globaluserinfo.merged; 						unattached = data.query.globaluserinfo.unattached; 					}  					callback( 						$div, 						username, 						guid, 						regdate, 						homewiki, 						merged, 						unattached 					); 				} else { 					alert( 'Error: Unknown result from API.' ); 				} 			}, 			error: function () { 				alert( 'Error: Request failed.' ); 			} 		}); 	},  	/** 	 * Taken almost verbatim from http://www.mediawiki.org/wiki/API:Edit 	 */ 	addNewSection: function ( $div, pagetitle, summary, content, editToken ) { 		$.ajax({ 			url: mw.util.wikiScript( 'api' ), 			data: { 				format: 'json', 				action: 'edit', 				title: pagetitle, 				section: 'new', 				summary: summary, 				text: content, 				token: editToken 			}, 			dataType: 'json', 			type: 'POST', 			success: function ( data ) { 				if ( data && data.edit && data.edit.result == 'Success' ) { 					showStatus( $div, phrases['result-label-status-ok'] ); 				} else if ( data && data.error ) { 					alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info ); 					showStatus( $div, phrases['result-label-status-error'] ); 				} else { 					alert( 'Error: Unknown result from API.' ); 					showStatus( $div, 'error2' ); 				} 			}, 			error: function () { 				alert( 'Error: Request failed.' ); 			} 		}); 	} };   /**  * Initialization function. Test if we should place the DRW on the current page.  */ function runRenameWizard() { 	var $nameInput, $nameResult, 		$nameContainer = $('#renameWizardCurrentInfo'), 		$searchInput, $searchResult, 		$searchContainer = $('#renameWizardSearchGlobal'), 		$mergeResult, $mergeFromInput, $mergeToInput, 		$mergeContainer = $('#renameWizardRequestMerge');  	if ( !$nameContainer.length && !$searchContainer.length && !$mergeContainer.length ) { 		return; 	}  	if ( $nameContainer.length ) {  			$nameInput = $('<input>').attr('size', 25); 			$nameResult = $('<div id="renameWizardCurrentInfoBox"></div>');  			$nameContainer 				.empty() 				.css({ 					width: '300px', 					border: '1px black solid', 					padding: '10px', 					margin: '10px' 				}) 				.append( $nameResult ) 				.append( 					$('<div>') 						.append( 							$('<hr width="60%"></hr>'), 							$('<p>Or search for Username</p>'), 							$nameInput, 							$('<a>').text('Search').on('click', function () { 								$nameResult.html( templates['icon-loading'] ); 								gRW.getGlobalInfo( $nameInput.val(), $nameResult, gRW.fillGlobalInfo ); 							}) 						) 				);  			// Asynchronously start fetching the info for the current user (if logged-in) 			gRW.setupCurrentInfo( $nameResult ); 	}  	if ( $searchContainer.length ) {  			$searchInput = $('<input>').attr('size', 25); 			$searchResult = $('<div id="renameWizardSearchResult"></div>');  			$searchContainer 				.empty() 				.css({ 					width: '300px', 					border: '1px black solid', 					padding: '10px', 					margin: '10px' 				}) 				.append( 					$('<h3>Search</h3>'), 					$searchInput, 					$('<a>').text('Search').on('click', function () { 						$searchResult.html( templates['icon-loading'] ); 						gRW.getGlobalInfo( $searchInput.val(), $searchResult, gRW.showSearchResult ); 					}), 					$searchResult 				); 	}  	if ( $mergeContainer.length ) {  			$mergeFromInput = $('<input>').attr('size', 25); 			$mergeToInput = $('<input>').attr('size', 25); 			$mergeResult = $('<div id="renameWizardMergeConfirm"></div>');  			$mergeContainer 				.empty() 				.css({ 					width: '600px', 					border: '1px black solid', 					padding: '10px', 					margin: '10px' 				}) 				.append( $('<p>').text( phrases['input-username-from'] ) ) 				.append( $mergeFromInput ) 				.append( $('<p>').text( phrases['input-username-to'] ) ) 				.append( $mergeToInput ) 				.append( $('<a>') 					.text( phrases['action-link-request'] ) 					.on('click', function () { 						$mergeResult.html( templates['icon-loading'] ); 						gRW.requestToName = $mergeToInput.val(); 						gRW.getGlobalInfo( $mergeFromInput.val(), $mergeResult, gRW.fillRequest ); 					}) 				) 				.append( $mergeResult ); 	} }  // Expose as global variable (TODO: Why? Is this used elsewhere?) window.gRW = gRW;  $( document ).ready( runRenameWizard );  }(mediaWiki, jQuery));