User:Samuele2002/Find and Replace.js

From Wikipedia

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.
// [[m:User:Indic-TechCom/Script/findAndreplace.js]]

$( document ).ready( function (){

	function init() {
		// Remove the default content
		$('#mw-content-text > p').remove();
    	$('#firstHeading').text('Find and Replace');
		
		// Create widget
		var listofPages = new OO.ui.MultilineTextInputWidget( {
            	placeholder: 'List of Pages',
            	autosize: true, 
            	rows: 10
        	} ),
	        findInput = new OO.ui.MultilineTextInputWidget( { 
	            placeholder: 'Trova',
				autosize: true, 
            	rows: 5
	        } ),
	        replaceInput = new OO.ui.MultilineTextInputWidget( { 
	            placeholder: 'Sostituisci',
	            autosize: true, 
            	rows: 5
	        } ),
	        reasonInput = new OO.ui.TextInputWidget( { 
	            placeholder: 'Motivo'
	        } ),
			replaceStart = new OO.ui.ButtonWidget( { 
			    label: 'Inizia sostituzioni', 
			    icon: 'alert',
			    flags: [ 'progressive' ]
			} ),
			cancelBtn = new OO.ui.ButtonWidget( {
			    label: 'Annulla',
			    flags: [ 'primary', 'destructive' ],
			    href: 'https:' + mw.config.get( 'wgServer' )
			} ),
			label1 = $('<p>').text('List of Pages:').css('font-weight','bold' ),
			label2 = $('<p>').text('Find:').css('font-weight','bold' ),
			label3 = $('<p>').text('Replace:').css('font-weight','bold' ),
			label4 = $('<p>').text('Reason:').css('font-weight','bold' ),
			divMainBox = $('<div />').css( {
				'box-shadow': '0 .5rem 1rem rgba(0, 0, 0, .15)',
				'border': '1px solid',
				'padding': '1rem',
				'margin-bottom': '3rem',
				'border-radius': '.5rem'
			}),
			divLog = $("<div />").hide(),
			orderedList = $("<ol />");
			
		divMainBox.append( 
            label1, listofPages.$element, 
            label2, findInput.$element,
            label3, replaceInput.$element,
            label4, reasonInput.$element,
            '<br/>',
            replaceStart.$element,
            cancelBtn.$element
		);
    	
		$( '#mw-content-text' ).append( divMainBox, '<br/>', divLog );

		// Replace button click event
		replaceStart.on( 'click', function() {

			pagesList = listofPages.getValue().replace(/^\s*[\r\n]/gm, '').split("\n");
			find = findInput.getValue().trim(),
			replace = replaceInput.getValue().trim(),
			reason = reasonInput.getValue().trim();
			
			// Check whether the all fields are enough to run the function
			if( pagesList[0].trim() !== "" && find !== "" && replace !== "" ) {
				divLog.empty();
				$("<h1>").wrapInner( "<span class='mw-headline'>Edit Log</span>").appendTo( divLog );
				orderedList.appendTo( divLog );
				divLog.show();
			} else {
				missingAlertMsg( "any source page" );
				return;
			}
			
			if ( find === "" ) {
				missingAlertMsg( "\'find\' string" );
				return;
			} else if ( replace === "" ) {
				missingAlertMsg( "replace string" );
				return;
			}

			pagesList.forEach( function(page){
				page = page.trim();

				var getContentParam = {
					"action": "query",
					"format": "json",
					"prop": "revisions",
					"titles": page,
					"rvprop": "content",
					"rvslots": "main",
					"rvlimit": "1"
				};
			
				api = new mw.Api();
				api.get( getContentParam, { async: false } ).done( function ( data ) {
					try {
						oldText = data.query.pages[Object.keys(data.query.pages)[0]].revisions[0].slots.main['*'];
					} catch(e){
						oldText = -1;
					}
	
					if( oldText !== -1 ){
						newText = safeReplace( oldText, find, replace );
						if ( newText === oldText){
							orderedList.append( "<li><b>" + page + "</b> Nessuna modifica necessaria.</li>" );
						} else{
							// Edit the page
							var editParams = {
								action: 'edit',
								title: page,
								text: newText,
								summary: reason,
								format: 'json'
							};

							api.postWithToken( 'csrf', editParams, { async: false } ).done( function ( res ) {
								if( res.edit.result === "Success"){
									orderedList.append( "<li>Modifiche apportate alla pagina <b>" + page + "</b></li>" );
								} else{
									orderedList.append( "<li>Qualcosa è andato storto nella pagina <b>" + page + "</b></li>" );
								}
							} );
						}
					} else {
						orderedList.append( "<li><b>[[" + page + "]]</b> non trovata.</li>" );
					}
				});
			});
    	});
	}

	function missingAlertMsg ( str ) {
		return alert( "Did not find " + str + " :(" );
		
	}

	function safeReplace( input, find, replaceText ) {
	    var flags = 'g';
	    
	    find = find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
	
	    var exclude = '(<!--[\\s\\S]*?-->|<(nowiki|math|source|syntaxhighlight|pre|gallery|timeline)[^>]*?>[\\s\\S]*?<\\/\\2>)';
	    var re = new RegExp(exclude + '|(' + find + ')', flags.replace(/i|$/, 'i'));
	    return input.replace(re, function(match, g1, g2, g3) {
			if (g3 !== undefined) {
				return match.replace(new RegExp(find, flags), replaceText);
			} else {
				return match;
			}
		});
	}
		
	// On every page
	$.when(mw.loader.using('mediawiki.util'), $.ready).then(function () {
	    mw.util.addPortletLink(
	    'p-tb',
	    mw.util.getUrl('Special:BlankPage/FindAndReplace'),
	    'Mass Find and Replace'
	    );
	});
	
	if ( mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && mw.config.get('wgTitle').split('/', 2)[1] === 'FindAndReplace' ) {
		mw.loader.using( ['oojs-ui-core', 'mediawiki.api'], init );
	}
});