MediaWiki:Gadget-pulsantipersonali.js: differenze tra le versioni

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Contenuto cancellato Contenuto aggiunto
aggiunge il valore al campo oggetto senza rimpiazzarlo, come da richiesta
Messaggio di avviso specifico per quando il JS personale non esiste.
 
Riga 58: Riga 58:
successHandler();
successHandler();
} ).fail( function ( code, data ) {
} ).fail( function ( code, data ) {
if ( code === 'nocreate-missing' ) {
mw.notify( 'Errore nell\'aggiornare ' + userConfig + ': ' + code );
mw.notify(
'Per poter inserire il testo personale è necessario prima creare la pagina ' +
userConfig + ', senza scriverci nulla. Prova di nuovo dopo averlo fatto.'
);
} else {
mw.notify( 'Errore nell\'aggiornare ' + userConfig + ': ' + code );
}
} );
} );
}
}

Versione attuale delle 12:38, 11 feb 2022

/**
 * Gadget-pulsantipersonali.js
 * Aggiunge alla toolbar di modifica normale e avanzata dek testo predefinito dall'utente
 * inseribile nell'area di modifica tramite una casella combinata.
 * Il testo è configurabile con una finestra di dialogo che si attiva dal menu strumenti.
 * Riscritto da zero a partire da:
 * https://it.wikipedia.org/w/index.php?title=Wikipedia:Monobook.js/Pulsanti_personali.js&oldid=10941967
 * http://it.wikipedia.org/w/index.php?title=MediaWiki:Gadget-pulsantipersonali.js&oldid=38709932
 * 
 * Formato di una entry, ereditato dal vecchio gadget (sarebbe da semplificare con un bot):
 * 0 (int):    tipo di inserimento: 1 per inizio e fine, 2 al cursore
 * 1 (string): testo prima del cursore
 * 2 (string): se il campo 0 vale 2 => testo dopo il cursore
 *             se il campo 0 vale 1 => '0' inserimento inizio, '1' inserimento fine
 * 3 (string): titolo
 * 4 (int):    offset
 * 5 (string): oggetto modifica
 *
 * @author https://it.wikipedia.org/wiki/Utente:Rotpunkt
 */
/* global mediaWiki, jQuery */

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

	// Configurazione utente
	var userConfig = 'User:' + mw.config.get( 'wgUserName' ) + '/' + mw.config.get( 'skin' ) + '.js';
	// Testo definito dell'utente (chiamato myButtons nel vector/monobook.js dell'utente)
	var userStrings;

	/**
	 * Aggiorna o aggiunge la variabile myButtons nel vector.js/monobook.js dell'utente.
	 * 
	 * @param {string} myButtonsValue - La stringa contenente il valore di myButtons da aggiornare
	 * @param {function} successHandler - La funzione da richiamare in caso di successo
	 */
	function updateUserConfig( myButtonsValue, successHandler ) {
		new mw.Api().edit( userConfig, function ( revision ) {
			var expr = /var\s+myButtons\s*=[\s\S]*?;\n/;
			myButtonsValue = 'var myButtons = ' + myButtonsValue + ';\n';
			var content = revision.content.match( expr ) ?
						  revision.content.replace( expr, myButtonsValue ) :
						  revision.content + '\n' + myButtonsValue;
			// eventuali tag pre
			content = content.indexOf( '//<pre>' ) === -1 ?
					  '//<pre>\n' + content : content;
			content = content.indexOf( '//</pre>' ) === -1 ?
					  content + '\n//</pre>' : content;
			return {
				text: content,
				summary: 'testo personale'
			};
		} ).done( function () {
			var url = mw.config.get( 'wgArticlePath' ).replace( '$1', userConfig );
			var msg = 'La configurazione del testo personale è stata aggiornata in <a href="' +
					  url + '" title="' + userConfig + '">' + userConfig + '</a>';
			mw.notify( $.parseHTML( msg ) );
			successHandler();
		} ).fail( function ( code, data ) {
			if ( code === 'nocreate-missing' ) {
				mw.notify(
					'Per poter inserire il testo personale è necessario prima creare la pagina ' +
					userConfig + ', senza scriverci nulla. Prova di nuovo dopo averlo fatto.'
				);
			} else {
				mw.notify( 'Errore nell\'aggiornare ' + userConfig + ': '  + code );
			}
		} );
	}

	/**
	 * Gestore del click del combobox per entrambe le toolbar.
	 * 
	 * @param {array} userString - L'elemento dell'array userStrings selezionato
	 */
	function clickHandler( userString ) {
		var text, post;
		text = userString[1].replace( /\\n/g, '\n' );
		post = userString[2].replace( /\\n/g, '\n' );
		if ( userString[0] === 2 ) {
			$( '#wpTextbox1' ).textSelection( 'encapsulateSelection', { pre: text, post: post } );
		} else if ( userString[0] === 1 && userString[2] === '0' ) {
			$( '#wpTextbox1' ).textSelection( 'setSelection', { start: 0, end: 0 } );
			$( '#wpTextbox1' ).textSelection( 'encapsulateSelection', { post: text + '\n' } );
		} else if ( userString[0] === 1 && userString[2] === '1' ) {
			$( '#wpTextbox1' ).select().val( $( '#wpTextbox1' ).val() + '\n' + text );
		}
		if ( userStrings[5] !== '' ) {
			$( '#wpSummary' ).val( function ( i, val ) {
				var sep = val.endsWith( ' ' ) ? '' : ' ';
				return ( val.trim() ? val + sep : '' ) + userString[5];
			} );
		}
	}

	/**
	 * Aggiunge la casella combinata alla toolbar di modifica avanzata.
	 */
	function addComboboxAdvancedToolbar() {
		var wb, tool;
		wb = { section: 'main', group: 'insert', tools: {} };
		tool = { label: 'Personale', type: 'select', list: {} };
		$.each( userStrings, function ( i, userString ) {
			tool.list[ 'gpp' + i ] = {
				label: userString[3],
				action: {
					type: 'callback',
					execute: function ( context ) {
						clickHandler( userString );
					}
				}
			};
		} );
		wb.tools.gpp = tool;
		$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', wb );
		// secondo tentativo per [[phab:T30563]]
		$( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', function () {
			var target = '#wikiEditor-ui-toolbar div[rel="main"].section ' +
						 'div[rel="insert"].group div[rel="gpp"].tool';
			if ( !$( target ).length ) {
				$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', wb );
			}
		} );
	}

	/**
	 * Aggiunge la casella combinata alla toolbar di modifica classica.
	 */
	function addComboboxClassicToolbar() {
		var $div, $select;
		$div = $( '<div>' ).attr( 'id', 'gpp-toolbar' )
			   .css( 'margin-bottom', '5px' ).insertBefore( '#toolbar' );
		$( '<span>' )
			.text( 'Testo personale:' )
			.appendTo( $div ).after( '&nbsp;' );
		$select = $( '<select>' ).appendTo( $div );
		$.each( userStrings, function ( i, userString ) {
			$( '<option>' )
				.html( userString[3] )
				.data( 'userString', userString )
				.appendTo( $select );
		} );
		$( '<input>' )
			.attr( 'type', 'button' )
			.attr( 'value', 'Ok' )
			.click( function () {
				clickHandler( $( 'option:selected' ).data( 'userString' ) );
			} )
			.appendTo( $div );
	}

	/**
	 * Rimuove la casella combinata dalla toolbar di modifica.
	 */
	function toolbarRemoveCombobox() {
		var target = mw.user.options.get( 'usebetatoolbar' ) ?
					'#wikiEditor-ui-toolbar div[rel="main"].section ' +
					'div[rel="insert"].group div[rel="gpp"].tool' :
					'#gpp-toolbar';
		$( target ).remove();
	}

	/**
	 * Funzione di utilità di buildRow per ottenere tipo di inserimento ('Cursore', 'Inizio', 'Fine').
	 * 
	 * @param {array} userString - Un elemento dell'array userStrings
	 * @return {string} la stringa '0', '1' o '2'
	 */
	function getPos( userString ) {
		return userString[0] === 1 && userString[2] === '0' ? '1' :
				userString[0] === 1 && userString[2] === '1' ? '2' :
						userString[0] === 2 ? '0' : '';
	}

	/**
	 * Funzione di utilità di showConfigDialog per creare una riga della tabella.
	 * 
	 * @param {array} userString - Un elemento dell'array userStrings
	 * @return {jQuery} la riga per la table
	 */
	function buildRow( userString ) {
		var $span, $input, $select, $tr = $( '<tr>' ),
			properties = {
				'width': '100%',
				'box-sizing': 'border-box',
				'-moz-box-sizing': 'border-box',
				'-webkit-box-sizing': 'border-box'
			};
		// icona spostamento
		$span = $( '<span>' ).addClass( 'ui-icon ui-icon-arrowthick-2-n-s' );
		$( '<td>' ).append( $span ).appendTo( $tr );
		// vecchi campi che contenevano il tipo di funzione da usare e l'offset
		$( '<input>' ).attr( 'type', 'hidden' ).val( userString[0] ).appendTo( $tr );
		$( '<input>' ).attr( 'type', 'hidden' ).val( userString[4] ).appendTo( $tr );
		// input text
		$input = $( '<input>' ).attr( 'type', 'text' ).val( userString[3] ).css( properties );
		$( '<td>' ).css( 'width', '16%' ).append( $input ).appendTo( $tr );
		$input = $( '<input>' ).attr( 'type', 'text' ).val( userString[1] ).css( properties );
		$( '<td>' ).css( 'width', '40%' ).append( $input ).appendTo( $tr );
		$input = $( '<input>' ).attr( 'type', 'text' ).val( userString[2] ).css( properties )
				 .toggle( userString[0] !== 1 );
		$( '<td>' ).css( 'width', '20%' ).append( $input ).appendTo( $tr );
		$input = $( '<input>' ).attr( 'type', 'text' ).val( userString[5] ).css( properties );
		$( '<td>' ).css( 'width', '20%' ).append( $input ).appendTo( $tr );
		// select
		$select = $( '<select>' ).change( function () {
			$input = $tr.find( 'input' );
			$input.eq( 0 ).val( $select.val() === '0' ? '2' : '1' );
			$input.eq( 4 ).val( $select.val() === '0' ? '' :
								$select.val() === '1' ? '0' : '1' )
							.toggle( $select.val() === '0' );
		} );
		$.each( [ 'Cursore', 'Inizio', 'Fine' ], function ( i, option ) {
			$( '<option>' ).val( i ).html( option ).appendTo( $select );
		} );
		$select.val( getPos( userString ) );
		$( '<td>' ).append( $select ).appendTo( $tr );
		// checkbox
		$( '<td>' ).append( $( '<input>' ).attr( 'type', 'checkbox' ) ).appendTo( $tr );
		return $tr;
	}

	/**
	 * Visualizza la finestra di dialogo per modificare il "testo personale".
	 */
	function showConfigDialog() {
		var $table, $thead, $tbody, $tr, $checkbox;

		// crea l'html del dialog, una singola table
		$table = $( '<table>' );
		$thead = $( '<thead>' ).appendTo( $table );
		$tr = $( '<tr>' ).attr( 'bgcolor', 'lightgrey' ).appendTo( $thead );
		$( '<th>' ).css( 'width', '2%' ).text( '' ).appendTo( $tr );
		$checkbox = $( '<input>' )
			.attr( 'id', 'gpp-selectall' )
			.attr( 'type', 'checkbox' )
			.attr( 'tabindex', '-1' )
			.click( function () {
				$( '#gpp-dialog :checkbox' ).prop( 'checked', this.checked );
			} );
		$( '<th>' ).css( 'width', '16%' ).text( 'Nome' ).appendTo( $tr );
		$( '<th>' ).css( 'width', '40%' ).text( 'Testo' ).appendTo( $tr );
		$( '<th>' ).css( 'width', '20%' ).text( 'Dopo cursore' ).appendTo( $tr );
		$( '<th>' ).css( 'width', '20%' ).text( 'Oggetto' ).appendTo( $tr );
		$( '<th>' ).text( 'Pos.' ).appendTo( $tr );
		$( '<th>' ).append( $checkbox ).appendTo( $tr );
		$tbody = $( '<tbody>' ).appendTo( $table );
		$.each( userStrings, function ( i, userString ) {
			$tbody.append( buildRow( userString ) );
		} );
		$tbody.sortable( { handle: 'span' } );
		$( '#gpp-dialog' ).html( $table );

		// visualizza il dialog
		$( '#gpp-dialog' ).dialog( {
			title: 'Configurazione testo personale',
			width: 800,
			height: 300,
			modal: true,
			buttons: {
				'Aggiungi riga': function () {
					$tbody.append( buildRow( [2, '', '', '', 0, ''] ) );
				},
				'Cancella riga': function () {
					$( '#gpp-dialog :checkbox:checked:not( #gpp-selectall )' ).parents( 'tr' ).remove();
					$( '#gpp-selectall' ).attr( 'checked', false );
				},
				'Salva': function () {
					var confStrings, confStringsJSON, userStringsJSON;
					// genera la nuova configurazione
					confStrings = $table.find( 'tr:has( td )' ).map( function () {
						var $input = $( this ).find( 'input' );
						return $.trim( $input.eq( 2 ).val() ) !== '' &&
							   $.trim( $input.eq( 3 ).val() ) !== '' ?
									[[ parseInt( $input.eq( 0 ).val(), 10 ), $input.eq( 3 ).val(),
										$input.eq( 4 ).val(), $input.eq( 2 ).val(),
										parseInt( $input.eq( 1 ).val(), 10 ), $input.eq( 5 ).val() ]] : null;
					} ).get();
					confStringsJSON = JSON.stringify( confStrings );
					userStringsJSON = JSON.stringify( userStrings );
					// se necessario scrive la configurazione nella pagina dell'utente
					if ( confStringsJSON === userStringsJSON ) {
						mw.notify( 'Il testo personale non è stato modificato.' );
					} else {
						updateUserConfig( confStringsJSON, function () {
							userStrings = confStrings;
							// aggiorna la toolbar
							if ( $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1 ) {
								toolbarRemoveCombobox();
								if ( userStrings.length > 0 ) {
									if ( mw.user.options.get( 'usebetatoolbar' ) ) {
										addComboboxAdvancedToolbar();
									} else {
										addComboboxClassicToolbar();
									}
								}
							}
						} );
					}
					$( this ).dialog( 'close' );
				},
				'Annulla': function () {
					$( this ).dialog( 'close' );
				}
			}
		} );
	}

	$( function () {
		userStrings = window.myButtons === undefined ? [] : window.myButtons;
		$( '<div>' ).attr( 'id', 'gpp-dialog' ).appendTo( 'body' );
		var portletLink = mw.util.addPortletLink( 'p-tb', '#', 'Testo personale' );
		$( portletLink ).click( function ( event ) {
			event.preventDefault();
			mw.loader.using( [ 'mediawiki.api', 'jquery.ui'], function () {
				showConfigDialog();
			} );
		} );
		if ( $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1 && userStrings.length > 0 ) {
			if ( mw.user.options.get( 'usebetatoolbar' ) ) {
				mw.loader.using( [ 'jquery.ui', 'ext.wikiEditor' ] )
					.done( addComboboxAdvancedToolbar )
					.fail( function () {
						console.error( 'Impossibile avviare l\'accessorio pulsanti personali.' );
					} );
			} else {
				addComboboxClassicToolbar();
			}
		}
	} );
}( mediaWiki, jQuery ) );