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

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Contenuto cancellato Contenuto aggiunto
rb test
m dimenticanza
(3 versioni intermedie di uno stesso utente non sono mostrate)
Riga 43: Riga 43:
* @param {string} prepend - Il wikicodice da inserire prima di quello esistente
* @param {string} prepend - Il wikicodice da inserire prima di quello esistente
* @param {string} summary - L'oggetto di modifica; per default è vuoto
* @param {string} summary - L'oggetto di modifica; per default è vuoto
* @param {boolean} minor - 'true' se la modifica dev'essere marcata come minore, 'false' altrimenti; per default viene lasciato il valore predefinito
* @param {boolean} minor - 'true' se la modifica dev'essere marcata come minore, 'false' se dev'essere marcata come non minore; altrimenti viene lasciato il valore predefinito
*/
*/
function autoEdit(prepend, summary="", minor=null) {
function autoEdit(prepend, summary, minor) {
if (prepend) {
if (prepend) {
// aggiungi il template nel codice
// aggiungi il template nel codice
let editBox = document.editform.wpTextbox1;
var editBox = document.editform.wpTextbox1;
editBox.value = prepend + editBox.value;
editBox.value = prepend + editBox.value;
Riga 60: Riga 60:
// salva la pagina
// salva la pagina
setTimeout(() => {
setTimeout(function() {
bannerMessage('Il pulsante per il salvataggio della pagina è stato cliccato automaticamente. Attendi che la pagina venga salvata.');
bannerMessage('Il pulsante per il salvataggio della pagina è stato cliccato automaticamente. Attendi che la pagina venga salvata.');
document.title = '(' + document.title + ')';
document.title = '(' + document.title + ')';
Riga 73: Riga 73:
$( function () {
$( function () {
// controlla se 1) siamo in un namespace di discussione 2) siamo in modalità modifica 3) il token passato in input è valido
// controlla se 1) siamo in un namespace di discussione 2) siamo in modalità modifica 3) il token passato in input è valido
if (mw.config.get('wgNamespaceNumber') % 2 === 1
if (mw.config.get('wgNamespaceNumber') % 2 === 1 &&
&& mw.config.get('wgAction') === 'edit'
mw.config.get('wgAction') === 'edit' &&
&& mw.util.getParamValue('tdtoken') === getAutoSaveToken()) {
mw.util.getParamValue('tdtoken') === getAutoSaveToken()) {
// ricava i parametri HTTP GET
// ricava i parametri HTTP GET
let [lang, title, timestamp, oldid] = ['tdlang', 'tdtitle', 'tdtimestamp', 'tdoldid']
var lang = mw.util.getParamValue('tdlang'),
.map(paramKey => mw.util.getParamValue(paramKey));
title = mw.util.getParamValue('tdtitle'),
timestamp = mw.util.getParamValue('tdtimestamp'),
oldid = mw.util.getParamValue('tdoldid');
if (lang && title && timestamp && oldid) {
if (lang && title && timestamp && oldid) {
// genera il wikicodice del template ed esegui l'edit automatico
// genera il wikicodice del template ed esegui l'edit automatico
let date = new Date(timestamp).toLocaleString('it-IT', {dateStyle:'long'});
var date = new Date(timestamp).toLocaleString('it-IT', {dateStyle:'long'});
let wikicode = `{{Tradotto da|${ lang }|${ title }|${ date }|${ oldid }}}\n`,
var wikicode = '{{Tradotto da|' + lang + '|' + title + '|' + date + '|' + oldid + '}}\n',
summary = "Aggiungo [[template:Tradotto da]] tramite [[Utente:Horcrux/CreditiTraduzione.js]]";
summary = "Aggiungo [[template:Tradotto da]] tramite [[Utente:Horcrux/CreditiTraduzione.js]]";
autoEdit(wikicode, summary);
autoEdit(wikicode, summary, null);
}
}
}
}
Riga 103: Riga 105:
* @param {string} timestamp - Il timestamp di riferimento (formato: "YYYY-MM-DDThh:mm:ssZ")
* @param {string} timestamp - Il timestamp di riferimento (formato: "YYYY-MM-DDThh:mm:ssZ")
* @return {Object} Un oggetto thenable contenente un array costituito dall'oldid desiderato e dal relativo timestamp.
* @return {Object} Un oggetto thenable contenente un array costituito dall'oldid desiderato e dal relativo timestamp.
*/
function getOtherWikiRevIdAndTimestamp( lang, title, timestamp ) {
return getOtherWikiRevIdAndTimestampAux( lang, title, timestamp, true );
}
/**
* Funzione ausiliaria per getOtherWikiRevIdAndTimestamp
*
* @param {boolean} firstAttempt - Valore booleano ausiliario, per sapere in quale direzione della cronologia effettuare la ricerca
* @param {boolean} firstAttempt - Valore booleano ausiliario, per sapere in quale direzione della cronologia effettuare la ricerca
*/
*/
function getOtherWikiRevIdAndTimestamp( lang, title, timestamp, firstAttempt = true ) {
function getOtherWikiRevIdAndTimestampAux( lang, title, timestamp, firstAttempt ) {
// Come da [[mw:API:Cross-site_requests#CORS_usage]]
// Come da [[mw:API:Cross-site_requests#CORS_usage]]
var apiEndpoint = `https://${ lang }.wikipedia.org/w/api.php`;
var apiEndpoint = 'https://' + lang + '.wikipedia.org/w/api.php';
var params = `action=query&prop=revisions&rvlimit=1&rvprop=ids|timestamp&titles=${ title }&rvstart=${ timestamp }`;
var params = 'action=query&prop=revisions&rvlimit=1&rvprop=ids|timestamp&titles=' + title + '&rvstart=' + timestamp;
var otherParams = firstAttempt ? '' : '&rvdir=newer';
var otherParams = firstAttempt ? '' : '&rvdir=newer';
return fetch(`${ apiEndpoint }?${ params }${ otherParams }&formatversion=2&format=json&origin=*`)
return fetch(apiEndpoint + '?' + params + otherParams + '&formatversion=2&format=json&origin=*')
.then(function(response){ return response.json(); })
.then(function(response) { return response.json(); })
.then(function(response) {
.then(function(response) {
if (typeof response.query.pages[0].revisions !== "undefined") {
if (typeof response.query.pages[0].revisions !== "undefined") {
Riga 120: Riga 130:
else if (firstAttempt) {
else if (firstAttempt) {
// se nessuna revision è trovata, prova invertendo la direzione di ricerca (rvdir=newer)
// se nessuna revision è trovata, prova invertendo la direzione di ricerca (rvdir=newer)
return getOtherWikiRevIdAndTimestamp(lang, title, timestamp, false);
return getOtherWikiRevIdAndTimestampAux(lang, title, timestamp, false);
}
}
});
});
Riga 256: Riga 266:
setResultLabel(' ');
setResultLabel(' ');
Promise.resolve(revisionId).then( (revId) => {
Promise.resolve(revisionId).then( function(revId) {
if (!revId) {
if (!revId) {
setResultLabel('<p>Impossibile trovare la versione specificata. Assicurati di trovarti nella pagina corretta e di indicare una versione valida.</p>');
setResultLabel('<p>Impossibile trovare la versione specificata. Assicurati di trovarti nella pagina corretta e di indicare una versione valida.</p>');
Riga 263: Riga 273:
getTimestampByRevisionId(revId),
getTimestampByRevisionId(revId),
getTitleByLang(lang)
getTitleByLang(lang)
]).then((values) => {
]).then( function(values) {
var [ timestamp, otherWikiTitle] = values;
var timestamp = values[0],
otherWikiTitle = values[1];
if (typeof otherWikiTitle === "undefined") {
if (typeof otherWikiTitle === "undefined") {
setResultLabel(`<p>Impossibile rintracciare la pagina di origine su ${ lang }.wiki. Assicurati di aver collegato questa pagina su Wikidata!</p>`);
setResultLabel('<p>Impossibile rintracciare la pagina di origine su ' + lang + '.wiki. Assicurati di aver collegato questa pagina su Wikidata!</p>');
}
}
else {
else {
getOtherWikiRevIdAndTimestamp(lang, otherWikiTitle, timestamp).then( (response) => {
getOtherWikiRevIdAndTimestamp(lang, otherWikiTitle, timestamp).then( function(response) {
var [otherWikiRevId, otherWikiTs] = response;
var otherWikiRevId = response[0],
otherWikiTs = response[1];
var autoEditUrl = `//it.wikipedia.org/wiki/${ currTitleObj.getTalkPage().getPrefixedText() }?action=edit&tdtoken=${ getAutoSaveToken() }`+
var autoEditUrl = '//it.wikipedia.org/wiki/' + currTitleObj.getTalkPage().getPrefixedText() + '?action=edit&tdtoken=' + getAutoSaveToken() +
`&tdlang=${ lang }&tdtitle=${ otherWikiTitle }&tdtimestamp=${ otherWikiTs }&tdoldid=${ otherWikiRevId }`;
'&tdlang=' + lang + '&tdtitle=' + otherWikiTitle + '&tdtimestamp=' + otherWikiTs + '&tdoldid=' + otherWikiRevId;
window.open(autoEditUrl,"_self");
window.open(autoEditUrl,"_self");
});
});

Versione delle 19:35, 20 ott 2022

/** 
 * Aggiunge il template {{Tradotto da}} in modo automatico nella pagina di discussione della pagina corrente.
 */
/* global mediaWiki, jQuery, OO */
( function ( mw, $ ) {
	'use strict';

	// la finestra di dialogo per l'inserimento delle informazioni sul template
	var inputDialog;
	var currTitle = mw.config.get('wgPageName');
	var currTitleObj = new mw.Title( currTitle );
	
	/*********************
	 * GESTIONE AUTOEDIT *
	 *********************/
	
	/**
	 * Restituisce un token che identifica la sessione utente, usato per convalidare il link per la modifica automatica.
	 * 
	 * @return {string} Una stringa alfanumerica.
	 */
	function getAutoSaveToken() {
		return mw.user.sessionId();
	}
	
	/**
	 * Aggiunge un banner temporaneo in cima alla pagina in attesa che questa venga salvata.
	 * 
	 * @param {string} s - Il messaggio da visualizzare
	 */
	function bannerMessage(s) {
		var headings = document.getElementsByTagName('h1');
		if (headings) {
			var div = document.createElement('div');
			div.innerHTML = '<div style="font-size:1.2em"><b>' + s + '</b></div>';
			headings[0].parentNode.insertBefore(div, headings[0]);
		}
	}
	
	/**
	 * Esegue la modifica automatica di una pagina.
	 * 
	 * @param {string} prepend - Il wikicodice da inserire prima di quello esistente
	 * @param {string} summary - L'oggetto di modifica; per default è vuoto
	 * @param {boolean} minor - 'true' se la modifica dev'essere marcata come minore, 'false' se dev'essere marcata come non minore; altrimenti viene lasciato il valore predefinito
	 */
	function autoEdit(prepend, summary, minor) {
		if (prepend) {
			// aggiungi il template nel codice
			var editBox = document.editform.wpTextbox1;
			editBox.value = prepend + editBox.value;
			
			// contrassegna la modifica come (non) minore
			if (minor === true || minor === false) {
				document.editform.wpMinoredit.checked = minor;
			}
			
			// aggiungi l'oggetto di modifica
			document.editform.wpSummary.value = summary;
			
			// salva la pagina
			setTimeout(function() {
				bannerMessage('Il pulsante per il salvataggio della pagina è stato cliccato automaticamente. Attendi che la pagina venga salvata.');
				document.title = '(' + document.title + ')';
				document.editform.wpSave.click();
			}, 500);
		}
	}
	
	/**
	 * La funzione seguente si occupa di far partire il processo di inserimento del template {{Tradotto da}}.
	 */
	$( function () {
		// controlla se 1) siamo in un namespace di discussione 2) siamo in modalità modifica 3) il token passato in input è valido
		if (mw.config.get('wgNamespaceNumber') % 2 === 1 &&
				mw.config.get('wgAction') === 'edit' &&
				mw.util.getParamValue('tdtoken') === getAutoSaveToken()) {
			// ricava i parametri HTTP GET
			var lang      = mw.util.getParamValue('tdlang'),
				title     = mw.util.getParamValue('tdtitle'),
				timestamp = mw.util.getParamValue('tdtimestamp'),
				oldid     = mw.util.getParamValue('tdoldid');
			
			if (lang && title && timestamp && oldid) {
				// genera il wikicodice del template ed esegui l'edit automatico
				var date = new Date(timestamp).toLocaleString('it-IT',  {dateStyle:'long'});
				var wikicode = '{{Tradotto da|' + lang + '|' + title + '|' + date + '|' + oldid + '}}\n',
					summary = "Aggiungo [[template:Tradotto da]] tramite [[Utente:Horcrux/CreditiTraduzione.js]]";
				autoEdit(wikicode, summary, null);
			}
		}
	} );
	
	
	/*****************************
	 * LOGICHE RECUPERO METADATI *
	 *****************************/

	/**
	 * Ricerca l'oldid e relativo timestamp di una voce di un'altra versione linguistica di Wikipedia
	 * in base al timestamp fornito (non necessariamente uguale a quello di output).
	 *
	 * @param {string} lang - La lingua del progetto in questione
	 * @param {string} title - Il titolo della pagina
	 * @param {string} timestamp - Il timestamp di riferimento (formato: "YYYY-MM-DDThh:mm:ssZ")
	 * @return {Object} Un oggetto thenable contenente un array costituito dall'oldid desiderato e dal relativo timestamp.
	 */
	function getOtherWikiRevIdAndTimestamp( lang, title, timestamp ) {
		return getOtherWikiRevIdAndTimestampAux( lang, title, timestamp, true );
	}
	
	/**
	 * Funzione ausiliaria per getOtherWikiRevIdAndTimestamp
	 * 
	 * @param {boolean} firstAttempt - Valore booleano ausiliario, per sapere in quale direzione della cronologia effettuare la ricerca
	 */
	function getOtherWikiRevIdAndTimestampAux( lang, title, timestamp, firstAttempt ) {
		// Come da [[mw:API:Cross-site_requests#CORS_usage]]
		var apiEndpoint = 'https://' + lang + '.wikipedia.org/w/api.php';
		var params = 'action=query&prop=revisions&rvlimit=1&rvprop=ids|timestamp&titles=' + title + '&rvstart=' + timestamp;
		var otherParams = firstAttempt ? '' : '&rvdir=newer';
		
		return fetch(apiEndpoint + '?' + params + otherParams + '&formatversion=2&format=json&origin=*')
			.then(function(response) { return response.json(); })
			.then(function(response) {
				if (typeof response.query.pages[0].revisions !== "undefined") {
					var revision = response.query.pages[0].revisions[0];
					return [revision.revid, revision.timestamp];
				}
				else if (firstAttempt) {
					// se nessuna revision è trovata, prova invertendo la direzione di ricerca (rvdir=newer)
					return getOtherWikiRevIdAndTimestampAux(lang, title, timestamp, false);
				}
			});
	}

	/**
	 * Ricava il titolo della voce di un'altra versione linguistica di Wikipedia.
	 * 
	 * @param {string} lang - Il codice della lingua
	 * @return {Object} Un oggetto thenable contenente una stringa che rappresenta il titolo della voce dell'altra versione linguistica,
	 *                  ma solo se è possibile ricavarla.
	 */
	function getTitleByLang( lang ) {
		return new mw.Api().get( {
			action: 'query',
			titles: currTitle,
			prop: 'langlinks',
			lllang: lang,
			format: 'json',
			formatversion: '2'
		} ).then( function ( response ) {
			// controlla se la voce è collegata ad un elemento Wikidata
			// e c'è almeno un sitelink ad un'altra versione linguistica
			if (typeof response.query.pages[0].langlinks !== "undefined") {
				return response.query.pages[0].langlinks[0].title;
			}
		} );
	}

	/**
	 * Ricava il timestamp relativo a un certo oldid.
	 * 
	 * @param {string} oldid - L'oldid di riferimento
	 * @return {Object} Un oggetto thenable contenente uil timestamp relativo all'oldid in input.
	 */
	function getTimestampByRevisionId( oldid ) {
		return new mw.Api().get( {
			action: 'query',
			prop: 'revisions',
			revids: oldid,
			rvprop: 'timestamp',
			format: 'json',
			formatversion: '2'
		} ).then( function ( response ) {
			return response.query.pages[0].revisions[0].timestamp;
		} );
	}
	
	/**
	 * Ricava l'identificativo della prima versione della pagina corrente.
	 * 
	 * @return {Object} Un oggetto thenable contenente l'oldid della prima versione della pagina corrente.
	 */
	function getFirstRevId() {
		return new mw.Api().get( {
			action: 'query',
			prop: 'revisions',
			titles: currTitle,
			rvlimit: '1',
			rvprop: 'ids',
			rvdir: 'newer',
			format: 'json',
			formatversion: '2'
		} ).then( function ( response ) {
			if (typeof response.query.pages[0].revisions !== "undefined") {
				return response.query.pages[0].revisions[0].revid;
			}
		} );
	}
	
	/**
	 * Ricava l'identificativo della versione attuale della pagina corrente.
	 * 
	 * @return {int} L'oldid della versione attuale della pagina corrente.
	 */
	function getCurrentRevId() {
		return mw.config.get('wgCurRevisionId');
	}

	/**
	 * Controlla se l'identificativo appartiene ad una versione.
	 * 
	 * @param {string} oldid - L'identificativo da controllare
	 * @return {Object} Un oggetto thenable contenente l'oldid in input, ma solo se questo è corretto.
	 */
	function checkRevId(oldid) {
		return new mw.Api().get( {
			action: 'query',
			revids: oldid,
			format: 'json',
			formatversion: '2'
		} ).then( function ( response ) {
			// controlla che l'oldid sia valido e che il titolo della voce corrisponda
			if (typeof response.query.pages !== "undefined" &&
				response.query.pages[0].title.replace(" ", "_") === currTitle) {
				return oldid;
			}
		} );
	}
	
	
	/**********************
	 * GESTIONE MODAL BOX *
	 **********************/
	
	/**
	 * Gestore del click sul pulsante "Inserisci template".
	 */
	function inputHandler() {
		function setResultLabel(html) {
			inputDialog.resultLabel.setLabel($( html ));
		}
		
		var lang = $.trim( inputDialog.langInput.getValue() );
		if (!lang) {
			setResultLabel('<p>Specificare il codice della versione linguistica da cui proviene la traduzione.</p>');
			return;
		}
		
		var revisionId;
		if      (inputDialog.firstRevRadio.isSelected()) revisionId = getFirstRevId();
		else if (inputDialog.currRevRadio.isSelected())  revisionId = getCurrentRevId();
		else if (inputDialog.otherRevRadio.isSelected()) {
			revisionId = $.trim( inputDialog.otherRevInput.getValue() );
			if (!revisionId) {
				setResultLabel('<p>Specificare l\'oldid della versione della voce.</p>');
				return;
			}
			else revisionId = checkRevId(revisionId);
		}
		else {
			setResultLabel('<p>Selezionare una delle tre opzioni.</p>');
			return;
		}
		setResultLabel(' ');
		
		Promise.resolve(revisionId).then( function(revId) {
			if (!revId) {
				setResultLabel('<p>Impossibile trovare la versione specificata. Assicurati di trovarti nella pagina corretta e di indicare una versione valida.</p>');
			}
			else Promise.all([
				getTimestampByRevisionId(revId),
				getTitleByLang(lang)
			]).then( function(values) {
				var timestamp      = values[0],
					otherWikiTitle = values[1];
				if (typeof otherWikiTitle === "undefined") {
					setResultLabel('<p>Impossibile rintracciare la pagina di origine su ' + lang + '.wiki. Assicurati di aver collegato questa pagina su Wikidata!</p>');
				}
				else {
					getOtherWikiRevIdAndTimestamp(lang, otherWikiTitle, timestamp).then( function(response) {
						var otherWikiRevId = response[0],
							otherWikiTs    = response[1];
						var autoEditUrl = '//it.wikipedia.org/wiki/' + currTitleObj.getTalkPage().getPrefixedText() + '?action=edit&tdtoken=' + getAutoSaveToken() +
							'&tdlang=' + lang + '&tdtitle=' + otherWikiTitle + '&tdtimestamp=' + otherWikiTs + '&tdoldid=' + otherWikiRevId;
						window.open(autoEditUrl,"_self");
					});
				}
			});
		});
	}

	/**
	 * Crea la finestra di dialogo per l'inserimento dei dettagli del template.
	 * Basato su [[Special:Permalink/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 langInput = new OO.ui.TextInputWidget();
			langInput.on( 'enter', inputHandler );
			var langInputLayout = new OO.ui.FieldLayout( langInput, {
				label: 'Codice lingua d\'origine:',
				align: 'top' 
			} );
			
			var radioInstrLabel = new OO.ui.LabelWidget( {
				label: $( '<br><p>In quale versione della <u>voce di it.wiki</u> è stata inserita la traduzione?</p>' )
			} );
			
			var firstRevRadio = new OO.ui.RadioOptionWidget( {
				data: 'first',
				label: 'Nella prima versione della voce'
			} );
			var currRevRadio = new OO.ui.RadioOptionWidget( {
				data: 'first',
				label: 'Nella versione attuale della voce'
			} );
			
			var otherRevInput = new OO.ui.TextInputWidget( { readOnly: true });
			otherRevInput.on( 'enter', inputHandler );
			var otherRevRadio = new OO.ui.RadioOptionWidget( {
				data: 'first',
				label: 'Altra versione (specificare oldid):'
			} );
			
			var radioSelect = new OO.ui.RadioSelectWidget( {
				items: [firstRevRadio, currRevRadio, otherRevRadio]
			} );
			radioSelect.on( 'choose', function(item) {
				otherRevInput.setReadOnly(item !== otherRevRadio);
			} );
			
			var resultLabel = new OO.ui.LabelWidget( {
				classes: [ 'grv-container' ],
				label: ' '
			} );
			
			var submitButton = new OO.ui.ButtonWidget( {
				label: 'Inserisci template {{Tradotto da}}',
			} ).on( 'click', inputHandler );
			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.langInput = langInput;
			this.currRevRadio = currRevRadio;
			this.firstRevRadio = firstRevRadio;
			this.otherRevRadio = otherRevRadio;
			this.otherRevInput = otherRevInput;
			this.resultLabel = resultLabel;
			this.panelLayout = new OO.ui.PanelLayout( { padded: true, expanded: false } );
			this.panelLayout.$element.append( langInputLayout.$element, radioInstrLabel.$element, radioSelect.$element,
				otherRevInput.$element, resultLabel.$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 () {
		var windowManager;
		var portletLink = mw.util.addPortletLink( 'p-navigation', '#', 'Aggiungi crediti traduzione' );
		$( portletLink ).click( function ( event ) {
			event.preventDefault();
			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 );
					} )
					.fail( function () {
						console.error( 'Impossibile avviare l\'accessorio "CreditiTraduzione".' );
					} );
		} );
	} );
}( mediaWiki, jQuery ) );