Jump to content

User:Horcrux/PingInSummary.js

From Meta, a Wikimedia project coordination wiki

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.
/** 
 * Aggiunge un pulsante "Ping" nella modalità modifica per facilitare la menzione di altri utenti nel campo oggetto.
 */
/* global mediaWiki, jQuery, OO */
( function ( mw, $ ) {
	'use strict';

	var windowManager;
	var inputDialog;
	
	/**
	 * Aggiunge i nomi utente nel campo oggetto
	 */
	function addPingInSummary() {
		var $summaryInput = $("#wpSummary");
		var summaryInput = $summaryInput[0];
		
		// ricava la posizione del cursore nel campo oggetto
		var caretPosition = summaryInput.selectionStart;
		
		// ricava il testo inserito dall'utente
		var inputText = inputDialog.pingInput.getValue();
		if (inputText !== null) {
			// dividi i nomi utenti in base alla barra verticale, togli gli spazi attorno e filtra i valori vuoti
			var usernames = inputText.split("|")
				.map( function(name) { return name.trim(); } )
				.filter( function(name) { return name !== ""; } );
			
			if (usernames.length !== 0) {
				// formatta i nomi utente per far arrivare la notifica
				var pings = "@" + usernames.map(function(name) {
					return "[[User:" + name + "|" + name + "]]";
				}).join(", ") + ": ";
				
				// aggiorna il campo oggetto
				var summaryText = summaryInput.value;
				summaryInput.value = summaryText.slice(0, caretPosition) + pings + summaryText.slice(caretPosition);
				
				// incrementa la posizione del cursore del numero di caratteri inseriti nell'oggetto
				caretPosition += pings.length;
			}
		}
		windowManager.$returnFocusTo = $summaryInput;
		windowManager.closeWindow(inputDialog)
			.closing.then(function () {
				summaryInput.setSelectionRange(caretPosition, caretPosition);
			});
	}

	/**
	 * Restituisce l'oggetto jQuery relativo al primo selettore valido tra quelli specificati in input.
	 * 
	 * @param {Array} selectors - Un array di selettori jQuery.
	 * @return {jQuery} Un oggetto jQuery, se almeno uno dei selettori in input funziona, altrimenti undefined.
	 */	
	function getFirstValidObject(selectors) {
		for (var i=0; i < selectors.length; i++) {
			var $obj = $(selectors[i]);
			if ($obj.length > 0) return $obj;
	    }
	}

	/**
	 * Copia la classe a partire dal primo selettore in input valido.
	 * 
	 * @param {Array} selectors - Un array di selettori jQuery.
	 * @return {string} Una stringa contenente la/le classe/i relative al primo selettore valido.
	 */	
	function copyClass(selectors) {
		var $obj = getFirstValidObject(selectors);
		if ($obj) {
			var cls = $obj.attr("class");
			if (cls) return cls;
		}
		return '';
	}

	/**
	 * Crea la finestra di dialogo per l'inserimento dei nomi utente da pingare.
	 * Basato su //it.wikipedia.org/w/index.php?oldid=109422525
	 * 
	 * @return {Object} L'oggetto derivato da OO.ui.Dialog che rappresenta la finestra
	 */
	function buildInputDialog() {
		var style = '.grv-container { height: 80px }' + 
					'.grv-container-button { width: 100%; text-align: center }';
		mw.util.addCSS( style );
		function InputDialog( config ) {
			InputDialog.parent.call( this, config );
		}
		OO.inheritClass( InputDialog, OO.ui.Dialog );
		InputDialog.static.name = 'inputDialog';
		InputDialog.prototype.initialize = function () {
			InputDialog.parent.prototype.initialize.call( this );
			
			var titleLabel = new OO.ui.LabelWidget( { label: $( '<b>Chi vuoi che riceva una notifica?</b>' ) } );
			var instrLabel = new OO.ui.LabelWidget( { label: 'Separa nomi utente diversi con una barra verticale ("|")' } );
			
			var pingInput = new OO.ui.TextInputWidget();
			pingInput.on( 'enter', addPingInSummary );
			
			var submitButton = new OO.ui.ButtonWidget( {
				label: 'Inserisci',
			} ).on( 'click', addPingInSummary );
			
			var cancelButton = new OO.ui.ButtonWidget( {
				label: 'Annulla'
			} ).on( 'click', function () {
				inputDialog.close();
			} );
			
			var buttons = new OO.ui.HorizontalLayout( {
				items: [ submitButton, cancelButton ],
				classes: [ 'grv-container-button' ]
			} );
			
			this.pingInput = pingInput;
			this.panelLayout = new OO.ui.PanelLayout( { padded: true, expanded: false } );
			this.panelLayout.$element.append( titleLabel.$element, instrLabel.$element, pingInput.$element, buttons.$element );
			this.$body.append( this.panelLayout.$element );
		};
		InputDialog.prototype.getBodyHeight = function () {
			return this.panelLayout.$element.outerHeight( true );
		};
		return new InputDialog( {
			size: 'small'
		} );
	}

	$( function () {
		if ([ "edit", "submit" ].includes(mw.config.get('wgAction'))) {
			var sibilingSelectors = ["#mw-editpage-minoredit", "#mw-editpage-watch"];
			var $sibiling = getFirstValidObject(sibilingSelectors);
			
			if ($sibiling !== undefined) {
				// copia lo stile di uno dei div fratelli
				var divClass = copyClass(sibilingSelectors);
				var $newDiv = $("<div/>", {
					id: "gadget-ping-in-summary",
					'class': divClass
				});
				
				// copia lo stile dello span di "Visualizza anteprima" o "Mostra modifiche" (il primo disponibile)
				var spanClass = copyClass(["#wpPreviewWidget", "#wpDiffWidget"]);
				var $newSpan = $("<span/>", {
					'class': spanClass
				});
			
				// copia lo stile del pulsante di input "Visualizza anteprima" o "Mostra modifiche" (il primo disponibile)
				var inputClass = copyClass(["#wpPreview", "#wpDiff"]);
				var $newInput = $("<input/>", {
					id: 'pingInSummary',
					'class': inputClass,
					type: 'button',
					tabindex: '5',
					title: 'Ping nel campo oggetto',
					value: 'Ping'
				});
				
				$newInput.click( function ( event ) {
					mw.loader.using( [ 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] )
							.done( function () {
								if ( !inputDialog ) {
									inputDialog = buildInputDialog();
									windowManager = new OO.ui.WindowManager();
									$( 'body' ).append( windowManager.$element );
									windowManager.addWindows( [ inputDialog ] );
								}
								windowManager.openWindow( inputDialog )
									.opened.then(function () {
										inputDialog.pingInput.focus();
									});
							} )
							.fail( function () {
								console.error( 'Impossibile avviare l\'accessorio "PingInSummary".' );
							} );
				} );
				
				$newSpan.append($newInput);
				$newDiv.append($newSpan);
				// aggiunge il pulsante in fondo sulla destra della checkbox "Aggiungi agli osservati speciali"
				$sibiling.parent().append($newDiv);
			}
			else {
				console.warn( 'Impossibile trovare la posizione in cui inserire il tasto "Ping".' );
			}
		}
	} );
}( mediaWiki, jQuery ) );