MediaWiki:Gadget-0xBlockMessage.js
Apparence
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;
Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5./*
* BlockMessage
*
* Permet d'ajouter un modèle notifiant le blocage d'un utilisateur en un clic,
* une fois le blocage réussi.
*
* Auteur : [[User:0x010C]]
* {{Projet:JavaScript/Script|BlockMessage}}
*/
// Customisation
var templatesList = {
finite: [
{
label: "Bloqué",
data: '{ "template": "Bloqué|$1|$2" }'
}, {
label: "Bloqué sans avertissement",
data: '{ "template": "Bloqué sans avertissement|$1|$2" }'
}, {
label: "Insultes",
data: '{ "template": "Insultes|$1|$2" }'
}, {
label: "IP partagée bloquée",
data: '{ "template": "IP partagée bloquée|$1|$2" }'
}, {
label: "Vandale scolaire bloqué",
data: '{ "template": "Vandale scolaire bloqué" }',
'autoselect-time': '15 july 2018'
}, {
label: "Proxy",
data: '{ "template": "Proxy|durée=$1|timestamp={{subst:'+'CURRENTTIMESTAMP}}", "default-subst": false }',
'autoselect-reason': '[[Wikipédia:Pas de serveurs mandataires ouverts|Proxy ouvert]]'
}, {
label: "IP bloquée pour 3 jours",
data: '{ "template": "Adresse IP bloquée pour trois jours|$3|$1|$2" }'
},
],
infinite: [
{
label: "Compte bloqué indéfiniment",
data: '{ "template": "Compte bloqué indéfiniment|$3", "default-clean": true }'
}, {
label: "Vandale bloqué indéfiniment",
data: '{ "template": "Vandale bloqué indéfiniment", "default-clean": true }'
}, {
label: "Vandale bloqué indéfiniment sans avertissement",
data: '{ "template": "Vandale bloqué indéfiniment sans avertissement", "default-clean": true }'
}, {
label: "Bot banni",
data: '{ "template": "Bot banni" }'
}, {
label: "Utilisateur rémunéré bloqué",
data: '{ "template": "Utilisateur rémunéré bloqué" }'
},
]
};
// I18n
var blockMessageMessages = {
'en': {
'blockmessage-default-header': 'Block user',
'blockmessage-success-header': 'Block succeeded',
'blockmessage-form-legend': 'Notify the user of the block',
'blockmessage-username-label': 'Username',
'blockmessage-template-label': 'Template',
'blockmessage-expiry-label': 'Duration',
'blockmessage-subst-label': 'Substitute the template',
'blockmessage-clean-label': 'Clear the talk page before putting the template',
'blockmessage-extra-label': 'Add a custom message under the template',
'blockmessage-extraTextareaLabel': '(be careful, the signature is no longer automatically added)',
'blockmessage-submit-label': 'Notify',
'blockmessage-message-summary': 'Block',
'blockmessage-message-tags': '0xBlockMessage',
'blockmessage-section-title': 'Block',
'blockmessage-successnotif': 'The message has been correctly added to the talk page.',
'blockmessage-time-label': 'Duration',
'blockmessage-unit-label': 'Unit',
'blockmessage-hour': 'hour',
'blockmessage-hours': 'hours',
'blockmessage-day': 'day',
'blockmessage-days': 'days',
'blockmessage-week': 'week',
'blockmessage-weeks': 'weeks',
'blockmessage-month': 'month',
'blockmessage-months': 'months',
'blockmessage-year': 'year',
'blockmessage-years': 'years',
'blockmessage-markup-element-not-found': 'Gadget 0xBlockMessage: markup element not found',
},
'fr': {
'blockmessage-default-header' : 'Bloquer l’utilisateur',
'blockmessage-success-header' : 'Blocage réussi',
'blockmessage-form-legend': 'Avertir du blocage',
'blockmessage-username-label': 'Utilisateur',
'blockmessage-template-label': 'Modèle',
'blockmessage-expiry-label': 'Expiration',
'blockmessage-subst-label': 'Substituer le modèle',
'blockmessage-clean-label': 'Effacer la PdD avant de mettre le modèle',
'blockmessage-extra-label': 'Rajouter un message sous le modèle',
'blockmessage-extraTextareaLabel': '(attention, la signature n\'est plus apposée automatiquement)',
'blockmessage-submit-label': 'Avertir',
'blockmessage-message-summary': 'Blocage',
'blockmessage-message-tags': '0xBlockMessage',
'blockmessage-section-title': 'Blocage',
'blockmessage-successnotif': 'La pose du message a réussi',
'blockmessage-time-label': 'Durée',
'blockmessage-unit-label': 'Unité',
'blockmessage-hour': 'heure',
'blockmessage-hours': 'heures',
'blockmessage-day': 'jour',
'blockmessage-days': 'jours',
'blockmessage-week': 'semaine',
'blockmessage-weeks': 'semaines',
'blockmessage-month': 'mois',
'blockmessage-months': 'mois',
'blockmessage-year': 'année',
'blockmessage-years': 'années',
'blockmessage-markup-element-not-found': 'Gadget 0xBlockMessage : élément de markup non trouvé',
}
};
mw.messages.set( blockMessageMessages[ 'en' ] );
var lang = mw.config.get( 'wgUserLanguage' );
if ( lang !== 'en' && lang in blockMessageMessages ) {
mw.messages.set( blockMessageMessages[ lang ] );
}
var blockMessageUnits = [
{ en: 'hour', data: mw.msg( 'blockmessage-hour' ), label: mw.msg( 'blockmessage-hour' ) },
{ en: 'hours', data: mw.msg( 'blockmessage-hours' ), label: mw.msg( 'blockmessage-hours' ) },
{ en: 'day', data: mw.msg( 'blockmessage-day' ), label: mw.msg( 'blockmessage-day' ) },
{ en: 'days', data: mw.msg( 'blockmessage-days' ), label: mw.msg( 'blockmessage-days' ) },
{ en: 'week', data: mw.msg( 'blockmessage-week' ), label: mw.msg( 'blockmessage-week' ) },
{ en: 'weeks', data: mw.msg( 'blockmessage-weeks' ), label: mw.msg( 'blockmessage-weeks' ) },
{ en: 'month', data: mw.msg( 'blockmessage-month' ), label: mw.msg( 'blockmessage-month' ) },
{ en: 'months', data: mw.msg( 'blockmessage-months' ), label: mw.msg( 'blockmessage-months' ) },
{ en: 'year', data: mw.msg( 'blockmessage-year' ), label: mw.msg( 'blockmessage-year' ) },
{ en: 'years', data: mw.msg( 'blockmessage-years' ), label: mw.msg( 'blockmessage-years' ) }
];
// Load the script only on the Block special page
if ( mw.config.get( 'wgCanonicalNamespace' ) === 'Special' && mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Block' ) {
mw.loader.using( [ 'mediawiki.cookie', 'mediawiki.util', 'oojs-ui', 'mediawiki.widgets.SelectWithInputWidget' ], function () {
$( function ( $ ) {
// On the Block page
if ( $( '#firstHeading' ).html() === mw.msg( 'blockmessage-default-header' ) ) {
var $expirySelect = $( '#mw-input-wpExpiry' ).find( 'select' );
var $expiryOther = $( 'input[name="wpExpiry-other"]' );
var $reasonSelect = $( '#mw-input-wpReason' ).find( 'select' );
var $reasonOther = $( 'input[name="wpReason-other"]' );
if (!$expirySelect.length || !$expiryOther.length || !$reasonSelect.length || !$reasonOther.length) {
mw.notify( mw.msg( 'blockmessage-markup-element-not-found' ), { type: 'error', autoHide: false } );
return;
}
$( 'form.mw-htmlform' ).submit( function ( event ) {
if ( $expirySelect.val() === 'other' ) {
mw.cookie.set( 'blockmessage-expiry', $expiryOther.val() );
}
else {
mw.cookie.set( 'blockmessage-expiry', $expirySelect.val() );
}
if ( $reasonSelect.val() === 'other' ) {
mw.cookie.set( 'blockmessage-reason', $reasonOther.val() );
}
else if ( $( 'input[name="wpReason-other"]' ).val() !== '' ) {
mw.cookie.set( 'blockmessage-reason', $reasonSelect.val() + ' : ' + $reasonOther.val() );
}
else {
mw.cookie.set( 'blockmessage-reason', $reasonSelect.val() );
}
} );
}
// When the user has successfully blocked someone.
// wgRelevantUserName may be null for IP ranges.
else if ( $( '#firstHeading' ).html() === mw.msg( 'blockmessage-success-header' ) &&
mw.cookie.get( 'blockmessage-expiry' ) !== null &&
mw.config.get( 'wgRelevantUserName' ) !== null ) {
window.blockMessage = new BlockMessage( mw.config.get( 'wgRelevantUserName' ), mw.cookie.get( 'blockmessage-reason' ), mw.cookie.get( 'blockmessage-expiry' ) );
}
} );
} );
}
/**
* @class BlockMessage
* @constructor
* @private
* @param {String} targetUser
* @param {String} reason
* @param {String} duration
*/
var BlockMessage = function (targetUser, reason, duration) {
this.targetUser = targetUser;
this.reason = reason;
this.duration = duration;
this.usernameInput;
this.templateDropdownInput;
this.expiryInput;
this.substCheckboxInput;
this.cleanCheckboxInput;
this.extraCheckboxInput;
this.extraTextarea;
this.submitInput;
this.expiryField;
this.extraTextareaField;
this.form;
// Initialize the form
this.createWidgets();
this.addEventHandlers();
this.initializeWidgets();
// Add the form to the page once all is ready
$( '#mw-content-text' ).append( this.form.$element );
};
/**
* Create all the OOjs-ui widgets and organise them into a field layout
*/
BlockMessage.prototype.createWidgets = function () {
this.usernameInput = new OO.ui.TextInputWidget( {
name: 'username',
disabled: 'disabled'
} );
this.templateDropdownInput = new OO.ui.DropdownInputWidget();
this.expiryInput = new mw.widgets.SelectWithInputWidget( {
or: false,
dropdowninput: {
label: mw.msg( 'blockmessage-unit-label' ),
options: blockMessageUnits,
},
textinput: {
placeholder: mw.msg( 'blockmessage-time-label' )
}
} );
this.substCheckboxInput = new OO.ui.CheckboxInputWidget( {
name: '',
selected: true
} );
this.cleanCheckboxInput = new OO.ui.CheckboxInputWidget( {
name: '',
selected: false
} );
this.extraCheckboxInput = new OO.ui.CheckboxInputWidget( {
name: '',
selected: false
} );
this.extraTextarea = new OO.ui.MultilineTextInputWidget( {
rows: 10,
autosize: true,
} );
this.submitInput = new OO.ui.ButtonInputWidget( {
type: 'submit',
label: mw.msg( 'blockmessage-submit-label' ),
flags: [ 'primary', 'destructive' ],
} );
this.expiryField = new OO.ui.FieldLayout( this.expiryInput, {
align: 'top',
label: mw.msg( 'blockmessage-expiry-label' )
} );
this.extraTextareaField = new OO.ui.FieldLayout( this.extraTextarea, {
align: 'top',
label: $( '<small>' ).text( mw.msg( 'blockmessage-extraTextareaLabel' ) )
} );
this.form = new OO.ui.FieldsetLayout( {
id: 'demo-section-formLayout',
label: mw.msg( 'blockmessage-form-legend' ),
items: [
new OO.ui.FieldLayout( this.usernameInput, {
align: 'top',
label: mw.msg( 'blockmessage-username-label' )
} ),
new OO.ui.FieldLayout( this.templateDropdownInput, {
align: 'top',
label: mw.msg( 'blockmessage-template-label' )
} ),
this.expiryField,
new OO.ui.FieldLayout( this.substCheckboxInput, {
align: 'inline',
label: mw.msg( 'blockmessage-subst-label' )
} ),
new OO.ui.FieldLayout( this.cleanCheckboxInput, {
align: 'inline',
label: mw.msg( 'blockmessage-clean-label' )
} ),
new OO.ui.FieldLayout( this.extraCheckboxInput, {
align: 'inline',
label: mw.msg( 'blockmessage-extra-label' )
} ),
this.extraTextareaField,
new OO.ui.FieldLayout( this.submitInput )
]
} );
};
/**
* Add some handlers to the widgets to manage the post-submit stage
* and to enhance the user experience
*/
BlockMessage.prototype.addEventHandlers = function () {
var self = this;
// Launch the postMessage method when the user submit the form
this.submitInput.on( 'click', function () {
self.submitInput.setDisabled(true);
self.postMessage();
} );
// Auto (un)check the checkboxes when the user change the selected template
this.templateDropdownInput.on( 'change', function (value) {
value = JSON.parse(value);
if ( value.hasOwnProperty( 'default-subst' ) ) {
self.substCheckboxInput.setSelected( value[ 'default-subst' ] );
}
if ( value.hasOwnProperty( 'default-clean' ) ) {
self.cleanCheckboxInput.setSelected( value[ 'default-clean' ] );
}
} );
// Display or hide the extra textarea when the user (un)check the extra checkbox
this.extraCheckboxInput.on( 'change', function ( checked ) {
self.extraTextareaField.toggle( checked );
} );
};
/**
* Populate and adapt parameters from the widgets
*/
BlockMessage.prototype.initializeWidgets = function () {
var templates;
if ( this.duration === 'infinite' ) {
// Hide the expiry field when the duration is infinite (it's irrelevant)
this.expiryField.toggle( false );
templates = templatesList.infinite;
}
else {
templates = templatesList.finite;
// Parse the expiry parameter and populate the expiration fields
if ( this.duration !== null ) {
var splitedDuration = this.duration.split( ' ' );
if ( splitedDuration.length === 2 && !isNaN( splitedDuration[ 0 ] ) ) {
for ( var i=0; i<blockMessageUnits.length; i++) {
if ( splitedDuration[ 1 ] === blockMessageUnits[ i ].en ) {
this.expiryInput.dropdowninput.setValue( blockMessageUnits[ i ].data );
this.expiryInput.textinput.setValue( splitedDuration[ 0 ] );
this.expiryField.toggle( false );
break;
}
}
}
}
}
// Populate the template dropdown with the appropriate templates names
this.templateDropdownInput.setOptions( templates );
// Autoselect a template depending of the reasons or the duration
for ( var i=0; i<templates.length; i++ ) {
if ( 'autoselect-reason' in templates[ i ] ) {
if ( templates[ i ][ 'autoselect-reason' ] === this.reason ) {
this.templateDropdownInput.setValue( templates[ i ].data );
break;
}
}
if ( 'autoselect-duration' in templates[ i ] ) {
if ( templates[ i ][ 'autoselect-duration' ] === this.duration ) {
this.templateDropdownInput.setValue( templates[ i ].data );
break;
}
}
}
// Fill the username field with the username of the blocked user
this.usernameInput.setValue( this.targetUser );
// By default, hide the extra textarea
this.extraTextareaField.toggle( false );
};
/**
* Use the datas set in the form to prepare and post a blocking notification
* to the target user's talk page.
* Called when the user click on the submit button.
*/
BlockMessage.prototype.postMessage = function () {
var subst = '';
if ( this.substCheckboxInput.isSelected() ) {
subst = 'subst:';
}
var extra = ' ~~' + '~~';
if ( this.extraCheckboxInput.isSelected() ) {
extra = '\n\n' + this.extraTextarea.getValue();
}
// Prepare the template
var template = JSON.parse( this.templateDropdownInput.getValue() ).template;
template = template.replace( '$1', this.expiryInput.textinput.getValue() );
template = template.replace( '$2', this.expiryInput.dropdowninput.getValue() );
template = template.replace( '$3', this.reason );
// Prepare the payload which will be send to the API
var data = {
action: 'edit',
title: 'User talk:' + this.targetUser,
text: '{{' + subst + template + '}}' + extra,
summary: mw.msg( 'blockmessage-message-summary' ),
tags: mw.msg( 'blockmessage-message-tags' ),
};
if ( ! this.cleanCheckboxInput.isSelected() ) {
data.section = "new";
data.sectiontitle = mw.msg( 'blockmessage-section-title' );
}
// Send the payload
new mw.Api().postWithToken( 'csrf', data ).then( this.onMessagePosted.bind( this ) );
};
BlockMessage.prototype.onMessagePosted = function ( data ) {
// Display a visual information to the admin to confirm that the talk page has been edited
mw.notify( mw.msg( 'blockmessage-successnotif' ) );
// Clean the cookies
mw.cookie.set( 'blockmessage-expiry', null );
mw.cookie.set( 'blockmessage-reason', null );
// Redirect the admin to the target's talk page after a short delay
var self = this;
setTimeout( function () {
document.location.href = mw.util.getUrl( 'User talk:' + self.targetUser + '#footer' );
}, 750 );
};