MediaWiki:Gadget-Azioni-dopo-blocco.js

Da Semi del Verbo, l'enciclopedia dell'influenza del Vangelo sulla cultura

Nota: dopo aver pubblicato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti.

  • Firefox / Safari: tieni premuto il tasto delle maiuscole Shift e fai clic su Ricarica, oppure premi Ctrl-F5 o Ctrl-R (⌘-R su Mac)
  • Google Chrome: premi Ctrl-Shift-R (⌘-Shift-R su un Mac)
  • Internet Explorer / Edge: tieni premuto il tasto Ctrl e fai clic su Aggiorna, oppure premi Ctrl-F5
  • Opera: premi Ctrl-F5.
// <nowiki>

/**
 * Dopo che Speciale:Blocca ha eseguito con successo il blocco di un utente,
 * crea un form per scegliere azioni aggiuntive come l'inserimento di template
 * nella pagina utente, avvisi nella talk utente, con svuotamento e protezione delle pagine.
 * 
 * @author https://it.wikipedia.org/wiki/Utente:Rotpunkt
 */
/* global mediaWiki, jQuery, OO */

( function ( mw, $ ) {
	'use strict';

	/**
	 * Funzione di utilità per le etichette, restituisce il link a un template wiki.
	 * @param {string} tpl - Il nome del template.
	 */
	function getLinkTpl( tpl ) {
		return '{{<a target="_blank" href="' +
			   mw.config.get( 'wgArticlePath' ).replace( '$1', 'Template:' + tpl ) +
			   '">' + tpl + '</a>}}';
	}

	/**
	 * Ripulisce la cache di una pagina per forzare l'eventuale aggiornamento
	 * della categorizzazione automatica del template NomeUtenteInappropriato.
	 * @param {string} title - La pagina dove pulire la cache.
	 */
	function purge( title ) {
		new mw.Api().post( {
			action: 'purge',
			titles: title,
			format: 'json',
		} );
	}

	/**
	 * Protegge una pagina con il tipo di protezione specificato.
	 * @param {string} title - La pagina da proteggere.
	 * @param {string} reason - La motivazione da usare.
	 * @param {string} protections - Il tipo di protezione.
	 * @param {function} successHandler - La funzione da richiamare in caso di successo.
	 */
	function protect( title, reason, protections, successHandler ) {
		new mw.Api().postWithToken( 'csrf', {
			action: 'protect',
			title: title,
			protections: protections,
			reason: reason,
			watchlist: 'nochange',
			format: 'json',
		} ).then( function () {
			successHandler();
		} ).fail( function () {
			OO.ui.alert( 'Errore nel proteggere la pagina:' + title );
		} );
	}

	/**
	 * Sostituisce il contenuto di una pagina con quello specificato.
	 * @param {string} title - Il titolo della pagina.
	 * @param {string} newContent - Il nuovo contenuto.
	 * @param {boolean} nocreate - Se impostato a true la pagina non verrà creata se non esiste.
	 * @param {string}} summary - L'oggetto da usare per la modifica.
	 * @param {function} successHandler - La funzione da richiamare in caso di successo.
	 */
	function replaceContent( title, newContent, nocreate, summary, successHandler ) {
		new mw.Api().postWithEditToken( {
			action: 'edit',
			title: title,
			text: newContent,
			summary: summary,
			nocreate: nocreate,
			watchlist: 'nochange',
			format: 'json',
		} ).done ( function ( data ) {
			successHandler( true );
		} ).fail ( function ( code, data ) {
			if ( code === 'missingtitle' ) {
				successHandler( false );
			} else {
				OO.ui.alert( 'Errore nello svuotare la pagina: ' + title );
			}
		} );
	}

	/**
	 * Aggiunge una sezione alla pagina indicata.
	 * @param {string} title - Il titolo della pagina.
	 * @param {string} text - Il contenuto della sezione.
	 * @param {string} watchlist - Il corrispettivo parametro di API:Edit,
	 *							   un valore fra watch/unwatch/preferences/nochange
	 * @param {function} successHandler - La funzione da richiamare in caso di successo.
	 */
	 function newSection( title, text, watchlist, successHandler ) {
		new mw.Api().newSection( title, 'Avviso', text, { watchlist: watchlist } )
			.done( function ( data ) {
				successHandler();
			} )
			.fail ( function ( code, data ) {
				OO.ui.alert( 'Errore nel creare l\'avviso: ' + code );
			} );
	 }

	/**
	 * Crea il form per scegliere un'eventuale azione dopo il blocco utente.
	 * @param {string} username - Il nome dell'utente che è stato bloccato.
	 * @param {string} expiry - La durata che è stata data al blocco.
	 * @param {string} reason - La motivazione che è stata usata per il blocco.
	 * @param {array|null} blockedPages - Le pagine oggetto del blocco parziale o null
	 * @param {array|null} blockedNs - I namespace oggetto del blocco parziale o null
	 */
	function buildForm( username, expiry, reason, blockedPages, blockedNs ) {
		var fieldset = new OO.ui.FieldsetLayout( { 
			label: 'Azioni opzionali dopo il blocco utente',
			classes: [ 'gb-container' ]
		} );
		var tplRc = new OO.ui.RadioOptionWidget( {
			label: $( '<span>Aggiungi ' + getLinkTpl( 'Rc' ) + ' nella talk dell\'utente</span>' )
		} );
		var tplBlocco = new OO.ui.RadioOptionWidget( {
			label: $( '<span>Aggiungi ' + getLinkTpl( 'Blocco' ) + ' nella talk dell\'utente</span>' )
		} );
		var radioSelect = new OO.ui.RadioSelectWidget( { 
			items: [ tplRc, tplBlocco ] 
		} );
		var button = new OO.ui.ButtonWidget( {
			label: 'Inserisci avviso',
			classes: [ 'gb-container-button' ]
		} ).on( 'click', function () {
			var text;
			if ( tplRc.isSelected() ) {
				text = '{{Rc|' + expiry + '}} --~~~~';
			} else if ( tplBlocco.isSelected() ) {
				text = '{{Blocco|' + reason + '|' + expiry;
				if ( blockedPages ) {
					text += '|pagine = ' + blockedPages.join( ', ' );
				}
				if ( blockedNs ) {
					text += '|namespace = ' + blockedNs.join( ', ' );
				}
				text +=  '}} --~~~~';
			}
			if ( text ) {
				newSection( 'Discussioni utente:' + username, text, 'preferences', function () {
					OO.ui.alert( 'Avviso aggiunto con successo.' );
				} );
			} else {
				OO.ui.alert( 'Nessuna opzione selezionata' );
			}
		} );
		fieldset.addItems( [ radioSelect, button ] );

		$( "#mw-content-text" ).append( fieldset.$element );
	}

	/**
	 * Sostituisce {{BloccoInfinito}} alla pagina utente e alla talk utente.
	 * Pagina utente e talk sono poi protette, la talk non è creata se non esiste.
	 * @param {string} username - Il nome dell'utente che è stato bloccato.
	 * @param {boolean} createUP - Se creare o meno la pagina utente qualora non esista
	 */
	function doBloccoInfinito( username, createUP ) {
		var userText = '{{BloccoInfinito}}';
		var talkText = userText;
		var reason = 'utente bloccato infinito';
		replaceContent( 'Utente:' + username, userText, !createUP, reason, function ( exists ) {
			var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
			protect( 'Utente:' + username, reason, protections, function () {
				replaceContent( 'Discussioni utente:' + username, talkText, true, reason, function ( exists ) {
					var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
					protect( 'Discussioni utente:' + username, reason, protections, function () {
						OO.ui.alert( 'Modifiche e protezioni pagina completate con successo.' );
					} );
				} );
			} );
		} );
	}

	/**
	 * Sostituisce {{BloccoInfinito}} + {{Sockpuppet}} alla pagina utente e
	 * {{BloccoInfinito}} alla talk utente.
	 * Pagina utente e talk sono poi protette, la talk non è creata se non esiste.
	 * @param {string} username - Il nome dell'utente che è stato bloccato.
	 */	
	function doSockpuppet( username ) {
		OO.ui.prompt( 'L\'utente sockmaster dietro il sockpuppet, senza "Utente:"',
					  { title: 'Parametro obbligatorio' } ).done( function ( result ) {
			if ( result ) {
				var userText = '{{BloccoInfinito}}{{Sockpuppet|' + result + '}}';
				var talkText = '{{BloccoInfinito}}';
				var reason = 'utente bloccato infinito';
				replaceContent( 'Utente:' + username, userText, false, reason, function () {
					protect( 'Utente:' + username, reason, 'edit=sysop|move=sysop', function () {
						replaceContent( 'Discussioni utente:' + username, talkText, true, reason, function ( exists ) {
							var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
							protect( 'Discussioni utente:' + username, reason, protections, function () {
								OO.ui.alert( 'Modifiche e protezioni pagina completate con successo' );
							} );
						} );
					} );
				} );
			}
		} );
	}

	/**
	 * Sostituisce {{BloccoInfinito}} alla pagina utente e
	 * aggiunge {{BloccoNomeUtente}} nella talk utente.
	 * Pagina utente e talk sono poi protette.
	 * @param {string} username - Il nome dell'utente che è stato bloccato.
	 * @param {boolean} createUP - Se creare o meno la pagina utente qualora non esista
	 */
	function doBloccoNomeUtente( username, createUP ) {
		var userText = '{{BloccoInfinito}}';
		var talkText = '{{subst:BloccoNomeUtente}} --~~~~';
		var reason = 'utente bloccato infinito';
		replaceContent( 'Utente:' + username, userText, !createUP, reason, function ( exists ) {
			var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
			protect( 'Utente:' + username, reason, protections, function () {
				newSection( 'Discussioni utente:' + username, talkText, 'nochange', function () {
					protect( 'Discussioni utente:' + username, reason, 'edit=sysop|move=sysop', function () {
						purge( 'Discussioni utente:' + username );
						OO.ui.alert( 'Modifiche e protezioni pagina completate con successo' );
					} );
				} );
			} );
		} );
	}

	/**
	 * Crea il form per scegliere un'eventuale azione dopo il blocco utente (infinito).
	 * @param {string} username - Il nome dell'utente che è stato bloccato (infinito).
	 * @param {string} reason - La motivazione che è stata usata per il blocco (infinito).
	 */
	function buildFormInfinito( username, reason ) {
		var fieldset = new OO.ui.FieldsetLayout( { 
			label: 'Azioni opzionali dopo il blocco utente (infinito)',
			classes: [ 'gb-container' ]
		} );
		var tplBloccoInfinito = new OO.ui.RadioOptionWidget( {
			label: $( '<span>Sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' alla pagina utente e alla talk utente</span>' )
		} );
		var tplSockpuppet = new OO.ui.RadioOptionWidget( {
			label: $( '<span>Sostituisci ' +
				getLinkTpl( 'BloccoInfinito' ) + ' + ' + getLinkTpl( 'Sockpuppet' ) + ' alla pagina utente e ' +
				getLinkTpl( 'BloccoInfinito' ) + ' alla talk utente</span>' )
		} );
		var tplBloccoNomeUtente = new OO.ui.RadioOptionWidget( {
			label: $( '<span>Aggiungi ' + getLinkTpl( 'BloccoNomeUtente' ) + ' nella talk utente e sostituisci ' +
				   getLinkTpl( 'BloccoInfinito' ) + ' alla pagina utente</span>' )
		} );
		var radioSelect = new OO.ui.RadioSelectWidget( { 
			items: [ tplBloccoInfinito, tplSockpuppet, tplBloccoNomeUtente ]
		} );
		// Con {{bloccoinfinito}} e {{blocconomeutente}} permette di scegliere se creare la talk
		var creaPUCb = new OO.ui.CheckboxInputWidget( {
			disabled: true
		} );
		var creaPUField = new OO.ui.FieldLayout(
			creaPUCb,
			{
				label: 'Crea la pagina utente se non esiste',
				align: 'inline'
			}
		);
		radioSelect.on( 'choose', function () {
			var hide = !( tplBloccoInfinito.isSelected() || tplBloccoNomeUtente.isSelected() ),
				select = hide ? false : creaPUCb.isSelected();
			creaPUCb
				.setDisabled( hide )
				.setSelected( select );
		} );
		var button = new OO.ui.ButtonWidget( {
			label: 'Inserisci i template',
			classes: [ 'gb-container-button' ]
		} ).on( 'click', function () {
			if ( tplBloccoInfinito.isSelected() ) {
				doBloccoInfinito( username, creaPUCb.isSelected() );
			} else if ( tplSockpuppet.isSelected() ) {
				doSockpuppet( username );
			} else if ( tplBloccoNomeUtente.isSelected() ) {
				doBloccoNomeUtente( username, creaPUCb.isSelected() );
			} else {
				OO.ui.alert( 'Nessuna opzione selezionata' );
			}
		} );
		var notaLabel = new OO.ui.LabelWidget( {
			label: new OO.ui.HtmlSnippet( '<div style="margin-top:0.5em"><b>Nota</b>: pagina utente e talk sono quindi protette; la talk non &egrave; creata se non esiste (a parte con BloccoNomeUtente).</div>' )
		} );
		fieldset.addItems( [ radioSelect, creaPUField, notaLabel, button ] );

		$( "#mw-content-text" ).append( fieldset.$element );
	}

	/**
	 * Legge la query string della pagina corrente per ottenere i parametri del blocco.
	 */
	function parseQueryString() {
		var username = $( '#mw-content-text p a:first-child' ).text();
		var expiry = mw.util.getParamValue( 'gbexpiry' );
		var reason = mw.util.getParamValue( 'gbreason' );
		var blockedPages = null, blockedNs = null;
		if ( mw.util.getParamValue( 'gbpartial' ) === '1' ) {
			// @ToDo Keep these vars in a consistent format: either pipe-split,
			// comma-split, array, or anything else. Depends on the format used
			// by block templates.
			blockedPages = mw.util.getParamValue( 'gbpages' ).split( '|' );
			blockedNs = mw.util.getParamValue( 'gbnamespaces' ).split( '|' );
		}
		if ( username && expiry && reason ) {
			var style = '.gb-container { border: solid 1px; width: ' +
				(expiry === 'infinito' ? '640px' : '400px') +  '; padding: 20px; }' + 
				'.gb-container-button { width: 100%; text-align: center }';
			mw.util.addCSS( style );
			if ( expiry === 'infinito' ) {
				buildFormInfinito( username, reason );
			} else {
				buildForm( username, expiry, reason, blockedPages, blockedNs );
			}
		}
	}

	/**
	 * Aggiune la query string con i parametri gbexpiry e gbreason all'azione del form di Speciale:Blocca.
	 */
	function addQueryString() {
		$( 'form[action^="/wiki/Speciale:Blocca"]' ).submit( function () {
			var reason;
			// expiry
			var wpExpiry = $( 'select[name="wpExpiry"] option:selected' ).text();
			var wpExpiryOther = $( 'input[name="wpExpiry-other"]' ).val();
			// reason
			var wpReason = $( 'select[name="wpReason"] option:selected' ).text();
			var wpReasonOther = $( 'input[name="wpReason-other"]' ).val();
			if ( wpReasonOther ) {
				reason = wpReason == 'Altro' ? wpReasonOther : wpReason + ' ' + wpReasonOther;
			} else {
				reason = wpReason;
			}
			var isPartial = $('#mw-input-wpEditingRestriction input:checked').val() === 'partial';
			var partialBlockString = '&gbpartial=0';
			if ( isPartial ) {
				var blockedPages = $( 'textarea[name="wpPageRestrictions"]' ).val().split( '\n' );
				var blockedNs = $( 'textarea[name="wpNamespaceRestrictions"]' ).val().split( '\n' );
				partialBlockString = '&gbpartial=1&gbpages=' + encodeURIComponent( blockedPages.join( '|' ) ) +
					'&gbnamespaces=' + encodeURIComponent( blockedNs.join( '|' ) );
			}
			// query string
			var qs = '?gbexpiry=' + encodeURIComponent( wpExpiry === 'Altra durata:' ? wpExpiryOther : wpExpiry );
			qs += '&gbreason=' + encodeURIComponent( reason );
			qs += partialBlockString;
			$( this ).attr( 'action', $( this ).attr( 'action' ) + qs );
		} );
	}

	$( function () {
		if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Block' ) {
			if ( $( '#firstHeading' ).text() === 'Blocco eseguito' ) {
				parseQueryString();
			} else {
				addQueryString();
			}
		}
	} );
}( mediaWiki, jQuery ) );

// </nowiki>