MediaWiki:Gadget-Azioni-dopo-blocco.js
Questa pagina definisce alcuni parametri di aspetto e comportamento generale di tutte le pagine. Per personalizzarli vedi Aiuto:Stile utente.
Nota: dopo aver salvato è necessario pulire la cache del proprio browser per vedere i cambiamenti (per le pagine globali è comunque necessario attendere qualche minuto). Per Mozilla / Firefox / Safari: fare clic su Ricarica tenendo premuto il tasto delle maiuscole, oppure premere Ctrl-F5 o Ctrl-R (Command-R su Mac); per Chrome: premere Ctrl-Shift-R (Command-Shift-R su un Mac); per Konqueror: premere il pulsante Ricarica o il tasto F5; per Opera può essere necessario svuotare completamente la cache dal menù Strumenti → Preferenze; per Internet Explorer: mantenere premuto il tasto Ctrl mentre si preme il pulsante Aggiorna o premere Ctrl-F5.
// <nowiki>
/**
* Aggiunge un pulsante in Speciale:Blocca che apre un form dove si possono
* scegliere azioni aggiuntive per l'ultimo blocco dato all'utente selezionato,
* come l'inserimento di template nella sua pagina utente e/o l'inserimento di
* avvisi nella sua talk, con o senza svuotamento e protezione delle pagine.
*
* @author https://it.wikipedia.org/wiki/Utente:Rotpunkt
*/
/* global mediaWiki, jQuery, OO */
( function ( mw, $ ) {
'use strict';
var indefMsgs = {
bloccoInfinitoOption:
'Sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' alla pagina utente e alla talk utente',
sockpuppetOption:
'Sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' + ' + getLinkTpl( 'Sockpuppet' ) + ' alla pagina utente e ' + getLinkTpl( 'BloccoInfinito' ) + ' alla talk utente',
bloccoNomeUtenteOption:
'L\'opzione BloccoNomeUtente è disabilitata quando l\'utente non può modificare la propria talk (modificare il blocco oppure valutare le opzioni precedenti)',
nota:
'pagina utente e talk sono poi protette; la talk non è creata se non esiste (a parte con BloccoNomeUtente)'
};
var appealableIndefMsgs = {
bloccoInfinitoOption:
'Sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' alla pagina utente e aggiungi ' + getLinkTpl( 'Blocco' ) + ' nella talk utente',
sockpuppetOption:
'Sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' + ' + getLinkTpl( 'Sockpuppet' ) + ' alla pagina utente e aggiungi ' + getLinkTpl( 'Blocco' ) + ' nella talk utente',
bloccoNomeUtenteOption:
'Aggiungi ' + getLinkTpl( 'BloccoNomeUtente' ) + ' nella talk utente e sostituisci ' + getLinkTpl( 'BloccoInfinito' ) + ' alla pagina utente',
nota:
'la pagina utente è poi protetta; la talk non è creata se non esiste (a parte con BloccoNomeUtente)'
};
/**
* Funzione di utilità per le etichette, restituisce il link a un template wiki.
*
* @param {string} tpl - Il nome del template.
* @return {string}
*/
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, 'Blocco', 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 $form = $( '<div id="adb-form">' );
var fieldset = new OO.ui.FieldsetLayout( {
id: 'adb-fieldset',
label: 'Azioni opzionali dopo il blocco utente'
} );
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 undoButton = new OO.ui.ButtonWidget( {
label: 'Annulla'
} ).on( 'click', function () {
$form.remove();
} );
var confirmButton = new OO.ui.ButtonWidget( {
label: 'Inserisci avviso',
flags: [ 'primary', 'progressive' ]
} ).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.map( ns => `{{subst:ns:${ ns }}}` ).join( ', ' );
}
text += '}} --~~~~';
}
if ( text ) {
newSection( 'Discussioni utente:' + username, text, 'preferences', function () {
$form.remove();
OO.ui.alert( 'Avviso aggiunto con successo.' );
} );
} else {
OO.ui.alert( 'Nessuna opzione selezionata' );
}
} );
var buttonField = new OO.ui.FieldLayout(
new OO.ui.Widget( {
content: [
new OO.ui.HtmlSnippet( '<hr style="margin:16px 0">' ),
new OO.ui.HorizontalLayout( {
items: [
undoButton,
confirmButton
]
} )
]
} ),
{
align: 'top'
}
);
fieldset.addItems( [ radioSelect, buttonField ] );
$form
.append( '<h2>Azioni dopo il blocco</h2>', fieldset.$element )
.insertBefore( '#adb-button' );
fieldset.scrollElementIntoView();
}
/**
* Sostituisce {{BloccoInfinito}} alla pagina utente e la protegge.
* Sostituisce {{BloccoInfinito}} alla talk utente e la protegge se è stata impedita
* la modifica della talk all'utente, altrimenti aggiunge {{Blocco}} nella talk.
*
* @param {string} username - Il nome dell'utente che è stato bloccato.
* @param {string} reason - La motivazione che è stata usata per il blocco.
* @param {boolean} createUP - Se creare o meno la pagina utente qualora non esista.
* @param {boolean} appealAllowed - Se l'utente può chiedere una revisione del blocco.
* @param {function} successHandler - La funzione da richiamare in caso di successo.
*/
function doBloccoInfinito( username, reason, createUP, appealAllowed, successHandler ) {
var userText = '{{BloccoInfinito}}';
var summary = 'utente bloccato infinito';
replaceContent( 'Utente:' + username, userText, !createUP, summary, function ( exists ) {
var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
protect( 'Utente:' + username, summary, protections, function () {
if ( appealAllowed ) {
let talkText = '{{Blocco|' + reason + '|infinito}} --~~~~';
newSection( 'Discussioni utente:' + username, talkText, 'nochange', successHandler );
} else {
let talkText = '{{BloccoInfinito}}';
replaceContent( 'Discussioni utente:' + username, talkText, true, summary, function ( exists ) {
var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
protect( 'Discussioni utente:' + username, summary, protections, successHandler );
} );
}
} );
} );
}
/**
* Sostituisce {{BloccoInfinito}} + {{Sockpuppet}} alla pagina utente e la protegge.
* Sostituisce {{BloccoInfinito}} alla talk utente e la protegge se è stata impedita
* la modifica della talk all'utente, altrimenti aggiunge {{Blocco}} nella talk.
*
* @param {string} username - Il nome dell'utente che è stato bloccato.
* @param {string} reason - La motivazione che è stata usata per il blocco.
* @param {boolean} appealAllowed - Se l'utente può chiedere una revisione del blocco.
* @param {function} successHandler - La funzione da richiamare in caso di successo.
*/
function doSockpuppet( username, reason, appealAllowed, successHandler ) {
OO.ui.prompt(
'L\'utente sockmaster dietro il sockpuppet, senza "Utente:"',
{ title: 'Parametro obbligatorio' }
).done( function ( result ) {
if ( !result.trim() ) { return; }
var userText = '{{BloccoInfinito}}{{Sockpuppet|' + result + '}}';
var summary = 'utente bloccato infinito';
replaceContent( 'Utente:' + username, userText, false, summary, function () {
protect( 'Utente:' + username, summary, 'edit=sysop|move=sysop', function () {
if ( appealAllowed ) {
let talkText = '{{Blocco|' + reason + '|infinito}} --~~~~';
newSection( 'Discussioni utente:' + username, talkText, 'nochange', successHandler );
} else {
let talkText = '{{BloccoInfinito}}';
replaceContent( 'Discussioni utente:' + username, talkText, true, summary, function ( exists ) {
var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
protect( 'Discussioni utente:' + username, summary, protections, successHandler );
} );
}
} );
} );
} );
}
/**
* Sostituisce {{BloccoInfinito}} alla pagina utente e la protegge.
* Aggiunge {{BloccoNomeUtente}} nella talk utente.
*
* @param {string} username - Il nome dell'utente che è stato bloccato.
* @param {boolean} createUP - Se creare o meno la pagina utente qualora non esista.
* @param {function} successHandler - La funzione da richiamare in caso di successo.
*/
function doBloccoNomeUtente( username, createUP, successHandler ) {
var userText = '{{BloccoInfinito}}';
var talkText = '{{subst:BloccoNomeUtente}} --~~~~';
var summary = 'utente bloccato infinito';
replaceContent( 'Utente:' + username, userText, !createUP, summary, function ( exists ) {
var protections = exists ? 'edit=sysop|move=sysop' : 'create=sysop';
protect( 'Utente:' + username, summary, protections, function () {
newSection( 'Discussioni utente:' + username, talkText, 'nochange', successHandler );
} );
} );
}
/**
* 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).
* @param {boolean} appealAllowed - Se l'utente può chiedere una revisione del blocco.
*/
function buildFormInfinito( username, reason, appealAllowed ) {
var msgs = appealAllowed ? appealableIndefMsgs : indefMsgs;
var $form = $( '<div id="adb-form">' );
var fieldset = new OO.ui.FieldsetLayout( {
id: 'adb-fieldset',
label: 'Azioni opzionali dopo il blocco utente (infinito)'
} );
var tplBloccoInfinito = new OO.ui.RadioOptionWidget( {
label: $( '<span>' + msgs.bloccoInfinitoOption + '</span>' )
} );
var tplSockpuppet = new OO.ui.RadioOptionWidget( {
label: $( '<span>' + msgs.sockpuppetOption + '</span>' )
} );
var tplBloccoNomeUtente = new OO.ui.RadioOptionWidget( {
label: $( '<span>' + msgs.bloccoNomeUtenteOption + '</span>' ),
disabled: !appealAllowed
} );
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 undoButton = new OO.ui.ButtonWidget( {
label: 'Annulla'
} ).on( 'click', function () {
$form.remove();
} );
var confirmButton = new OO.ui.ButtonWidget( {
label: 'Inserisci i template',
flags: [ 'primary', 'progressive' ]
} ).on( 'click', function () {
var createUP = creaPUCb.isSelected();
var successHandler = () => {
$form.remove();
OO.ui.alert( 'Modifiche e protezioni pagina completate con successo' );
};
if ( tplBloccoInfinito.isSelected() ) {
doBloccoInfinito( username, reason, createUP, appealAllowed, successHandler );
} else if ( tplSockpuppet.isSelected() ) {
doSockpuppet( username, reason, appealAllowed, successHandler );
} else if ( tplBloccoNomeUtente.isSelected() ) {
doBloccoNomeUtente( username, createUP, successHandler );
} else {
OO.ui.alert( 'Nessuna opzione selezionata' );
}
} );
var buttonField = new OO.ui.FieldLayout(
new OO.ui.Widget( {
content: [
new OO.ui.HtmlSnippet( '<hr style="margin:16px 0">' ),
new OO.ui.HorizontalLayout( {
items: [
undoButton,
confirmButton
]
} )
]
} ),
{
align: 'top'
}
);
var notaLabel = new OO.ui.LabelWidget( {
label: new OO.ui.HtmlSnippet( '<div style="margin-top:0.5em"><b>Nota</b>: ' + msgs.nota + '.</div>' )
} );
fieldset.addItems( [ radioSelect, creaPUField, notaLabel, buttonField ] );
$form
.append( '<h2>Azioni dopo il blocco</h2>', fieldset.$element )
.insertBefore( '#adb-button' );
fieldset.scrollElementIntoView();
}
/**
* Esegue una chiamata API per ottenere i dati del blocco impostato.
*
* @param {string} username - Il nome dell'utente che è stato bloccato.
* @return {jQuery.Promise}
*/
function getLatestBlockData( username ) {
return new mw.Api().get( {
action: 'query',
list: 'blocks',
bkusers: username,
bkprop: 'id|user|by|timestamp|expiry|reason|flags|restrictions',
format: 'json',
formatversion: 2
} ).then( function ( data ) {
const blocks = data.query.blocks;
const filteredBlocks = blocks.filter( block => block.by === mw.config.get( 'wgUserName' ) );
return filteredBlocks.sort( ( b1, b2 ) => b1.id < b2.id )[ 0 ];
} );
}
/**
* Individua quale form creare in base ai dati del blocco impostato.
*/
function onAdbButtonClick() {
var blockedUser = decodeURI( window.___location.pathname.split( '/' ).pop() ).replaceAll( '_', ' ' );
getLatestBlockData( blockedUser ).done( function ( block ) {
if ( !block ) {
OO.ui.alert( `Non hai impostato un blocco per l\'utente ${ blockedUser }` );
return;
}
const {
user: username,
'duration-l10n': expiry,
reason,
allowusertalk: allowUserTalk,
partial: isPartial,
restrictions
} = block;
if ( !username || !expiry || !reason ) {
return;
}
if ( !isPartial && expiry === 'infinito' ) {
buildFormInfinito( username, reason, allowUserTalk );
} else {
const blockedPages = restrictions.pages
? restrictions.pages.map( page => page.title )
: null;
const blockedNs = restrictions.namespaces;
buildForm( username, expiry, reason, blockedPages, blockedNs );
}
} );
}
$( function () {
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) !== 'Block' ) {
return;
}
mw.loader.using( [
'mediawiki.api',
'mediawiki.util',
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows'
] ).done( function () {
const button = new OO.ui.ButtonWidget( {
id: 'adb-button',
label: 'Azioni dopo il blocco'
} ).on( 'click', onAdbButtonClick );
mw.util.addCSS( `
#adb-button {
margin-top: 4px;
}
#adb-fieldset {
margin-top: 16px;
}
#adb-form {
margin-top: 8px;
}
#adb-form + #adb-button,
#mw-block-form:not(:has(.mw-block-log)) + #adb-button {
display: none;
}
` );
$( '#mw-block-form' ).after( button.$element );
} );
} );
}( mediaWiki, jQuery ) );
// </nowiki>