MediaWiki:Gadget-collegamentipersonali.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.
/**
 * Gadget-collegamentipersonali.js
 * Aggiunge dei collegamenti personali al menu navigazione della sidebar.
 * I collegamenti sono configurabili in una pagina di configurazione con link nel menu strumenti.
 * Riscrittura da zero di:
 * https://it.wikipedia.org/w/index.php?title=Wikipedia:Monobook.js/Collegamenti_personali.js&oldid=32996648
 * http://it.wikipedia.org/w/index.php?title=MediaWiki:Gadget-collegamentipersonali.js&oldid=38993132
 *
 * @author https://it.wikipedia.org/wiki/Utente:Rotpunkt
 */
/* global mediaWiki, jQuery, OO */

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

	// Configurazione utente
	var userConfig = 'User:' + mw.config.get( 'wgUserName' ) + '/' + mw.config.get( 'skin' ) + '.js';
	// Collegamenti personali dell'utente (chiamato myLinks nel vector.js/monobook.js dell'utente)
	var userLinks;

	/**
	 * Aggiorna o aggiunge la variabile myLinks nel vector.js/monobook.js dell'utente.
	 * 
	 * @param {string} myLinksValue - La stringa contenente il valore di myLinks da aggiornare
	 * @param {function} successHandler - La funzione da richiamare in caso di successo
	 */
	function updateUserConfig( myLinksValue, successHandler ) {
		new mw.Api().edit( userConfig, function ( revision ) {
			var expr = /var\s+myLinks\s*=[\s\S]*?;/;
			myLinksValue = 'var myLinks = ' + myLinksValue + ';';
			var content = revision.content.match( expr ) ?
						  revision.content.replace( expr, myLinksValue ) :
						  revision.content + '\n' + myLinksValue;
			return {
				text: content,
				summary: 'collegamenti personali'
			};
		} ).done( function () {
			var url = mw.config.get( 'wgArticlePath' ).replace( '$1', userConfig );
			var msg = 'La configurazione dei collegamenti personali è stata aggiornata in <a href="' +
					  url + '" title="' + userConfig + '">' + userConfig + '</a>';
			mw.notify( $.parseHTML( msg ) );
			successHandler();
		} ).fail( function ( code, data ) {
			mw.notify( 'Errore nell\'aggiornare ' + userConfig + ': '  + code );
		} );
	}

	/**
	 * Aggiorna i portlet link in base al valore corrente di userLinks.
	 */
	function updatePortletLinks() {
		var url;
		$( 'li[id^=t-gcp]' ).remove();
		$.each( userLinks, function ( i, userLink ) {
			url = userLink[ 1 ].replace( '%TITOLO%', mw.config.get( 'wgPageName' ) );
			url = url.replace( '%TITOLO2%', mw.config.get( 'wgTitle' ) );
			mw.util.addPortletLink( 'p-navigation', url, userLink[ 0 ], 't-gcp' + i );
		} );
	}

	/**
	 * @class DraggableRow
	 * @extends OO.ui.HorizontalLayout
	 * @mixins OO.ui.mixin.DraggableElement
	 *
	 * @constructor
	 * @param {Object} config - Opzioni di configurazione
	 */
	function DraggableRow( config ) {
		DraggableRow.parent.call( this, config );
		this.dragIcon = new OO.ui.IconWidget( { icon: 'draggable' } );
		this.dragIcon.toggle( false );
		this.$icon = this.dragIcon.$element;
		OO.ui.mixin.DraggableElement.call( this, $.extend( { $handle: this.$icon }, config ) );
		this.$element.append( this.$icon );
	}

	/**
	 * @class DraggableGroupRow
	 * @extends OO.ui.Widget
	 * @mixins OO.ui.mixin.DraggableGroupElement
	 *
	 * @constructor
	 * @param {Object} config - Opzioni di configurazione
	 */
	function DraggableGroupRow( config ) {
		DraggableGroupRow.parent.call( this, config );
		OO.ui.mixin.DraggableGroupElement.call( this,
			$.extend( {}, config, { $group: this.$element } ) );
	}

	/**
	 * Funzione di utilità di buildConfigPage per creare una riga della tabella.
	 * 
	 * @param {array} userLink - Un elemento dell'array userLinks
	 * @return {DraggableRow} - La nuova riga
	 */
	function buildRow( userLink ) {
		return new DraggableRow( {
			items: [
				new OO.ui.TextInputWidget( {
					value: userLink[ 0 ],
					classes: [ 'gcp-container-name' ]
				} ),
				new OO.ui.TextInputWidget( {
					value: userLink[ 1 ],
					classes: [ 'gcp-container-url' ]
				} ),
				new OO.ui.CheckboxInputWidget()
			]
		} );
	}

	/**
	 * Crea la pagina per modificare i "collegamenti personali".
	 */
	function buildConfigPage() {
		var style = '.gcp-container-button { margin-top: 10px }' + 
			'.gcp-container-name { width: 150px; margin-top: 5px }' +
			'.gcp-container-url { width: 550px; margin-top: 5px }';
		mw.util.addCSS( style );
		
		// classe DraggableRow
		OO.inheritClass( DraggableRow, OO.ui.HorizontalLayout );
		OO.mixinClass( DraggableRow, OO.ui.mixin.DraggableElement );
		// classe DraggableGroupRow
		OO.inheritClass( DraggableGroupRow, OO.ui.Widget );
		OO.mixinClass( DraggableGroupRow, OO.ui.mixin.DraggableGroupElement );
		// righe
		var rows = new DraggableGroupRow();
		$.each( userLinks, function ( i, userLink ) {
			rows.addItems( buildRow( userLink ) );
		} );
		rows.toggleDraggable( false );
		// pulsanti
		var addButton = new OO.ui.ButtonWidget( {
			label: 'Aggiungi riga',
		} ).on( 'click', function () {
			rows.addItems( buildRow( [ '', '' ] ) );
		} );
		var delButton = new OO.ui.ButtonWidget( {
			label: 'Cancella riga'
		} ).on( 'click', function () {
			$.each( rows.getItems(), function ( idx, row ) {
				if ( row.getItems()[ 2 ].isSelected() ) {
					rows.removeItems ( row );
					row.toggle( false );
				}
			} );
		} );
		var saveButton = new OO.ui.ButtonWidget( {
			label: 'Salva'
		} ).on( 'click', function () {
			var confLinks = [], confLinksJSON, userLinksJSON;

			// genera la nuova configurazione
			$.each( rows.getItems(), function( idx, row ) {
				var nome = $.trim( row.getItems()[ 0 ].getValue() );
				var indirizzo = $.trim( row.getItems()[ 1 ].getValue() );
				if ( nome && indirizzo ) {
					confLinks.push( [ nome, indirizzo ] );
				}
			} );
			confLinksJSON = JSON.stringify( confLinks );
			userLinksJSON = JSON.stringify( userLinks );
			// se necessario scrive la configurazione nella pagina dell'utente
			if ( confLinksJSON === userLinksJSON ) {
				mw.notify( 'I collegamenti personali non sono stati modificati.' );
			} else {
				// aggiorna la configurazione
				updateUserConfig( confLinksJSON, function () {
					userLinks = confLinks;
					// aggiorna i link
					updatePortletLinks();
				} );
			}
		} );
		// checkbox riordina
		var dragCheckbox = new OO.ui.CheckboxInputWidget();
		dragCheckbox.on( 'change', function () {
			rows.toggleDraggable( dragCheckbox.isSelected() );
			$.each( rows.getItems(), function( idx, row ) {
				row.dragIcon.toggle( dragCheckbox.isSelected() );
			} );
		} );

		var fieldset = new OO.ui.FieldsetLayout( {
			items: [
				new OO.ui.HorizontalLayout( {
					items: [
						new OO.ui.LabelWidget( {
							label: $( '<b>Nome</b>' ),
							classes: [ 'gcp-container-name' ]
						} ),
						new OO.ui.LabelWidget( {
							label: $( '<b>Indirizzo</b>' ),
							classes: [ 'gcp-container-url' ]
						} ),
					]
				} ),
				rows,
				new OO.ui.FieldLayout( dragCheckbox, {
					label: 'Righe riordinabili', align: 'inline'
				} ),
				new OO.ui.HorizontalLayout( {
					items: [ addButton, delButton, saveButton ],
					classes: [ 'gcp-container-button' ]
				} )
			]
		} );
		document.title = 'Configurazione collegamenti personali';
		$( 'h1' ).text( 'Configurazione collegamenti personali' );
		$( '#mw-content-text' ).replaceWith( fieldset.$element );
	}

	$( function () {
		userLinks = window.myLinks === undefined ? [] : window.myLinks;
		// portletLink per la pagina di configurazione
		var url = mw.config.get( 'wgArticlePath' ).replace( '$1', 'Speciale:PaginaVuota/Collegamenti personali' );
		mw.util.addPortletLink( 'p-tb', url, 'Collegamenti personali' );
		// collegamenti già configurati
		if ( userLinks.length > 0 ) {
			updatePortletLinks();
		}
		if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Blankpage' &&
			 mw.config.get( 'wgTitle' ).split( '/' )[ 1 ] === 'Collegamenti personali' ) {
			mw.loader.using( [ 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] )
				.done( buildConfigPage )
				.fail( function () {
					console.error( 'Impossibile avviare il gadget collegamentipersonali.' );
				} );
		}
	} );
}( mediaWiki, jQuery ) );