MediaWiki:Gadget-common.js

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.
// importazione di prova di nuovo script; chiamata con newAutoRi(header)
//importScript("Utente:Alex brollo/autoRi.js");
function newAutoRi(header) {
	function incrementa(t){
		var pagina=/(\d+)/.exec(t)[1];
		var pnew=(pagina*1+2)+"";https://it.wikisource.org/w/index.php?title=MediaWiki:Gadget-common.js&action=edit
		return t.replace(pagina,pnew);
	}
	// normalizzazione RigaIntestazione
	header=header.replace("{{Ri|","{{RigaIntestazione|")
		.replace("{{ri|","{{RigaIntestazione|")
		.replace("{{rigaIntestazione|","{{RigaIntestazione|");

	var oldRi=find_stringa(header,"{{RigaIntestazione|","}}",1,"{{");
	if (oldRi==="") return header;
	var parsedRi=parseTemplate("RigaIntestazione",oldRi);
	// analisi
	var valido=[];
	var pagina="";
	for (i=1;i<4;i+=1) {
		if (/^\d+$/.test(parsedRi[0][i]) || /— \d+ —/.test(parsedRi[0][i]) || /\|\d+}/.test(parsedRi[0][i])) valido.push(i);
	}
	// console.log(valido,parsedRi);
	switch (valido.length) {
		case 0:
			break;
		case 1:
			// pagina=/(\d+)/.exec(parsedRi[0][valido[0]])[1];
			parsedRi[0][valido[0]]=incrementa(parsedRi[0][valido[0]]);
			break;
		default:
			break;
	}

	return header.replace(oldRi,rewriteTemplate(parsedRi));
}
window.newAutoRi = newAutoRi;

// console.log("common.js versione 24.02.2018");
// se la pagina esiste restituisce il wikitext altrimenti restituisce ""
function getWikitext(pagina) {
	if(pagina===undefined) {
		pagina=mw.config.get("wgPageName");
	}
	var contenuto=JSON.parse($.ajax({url: "/w/api.php?action=parse&page="+pagina+"&prop=wikitext&format=json",
				async: false
				}).responseText);
    if (contenuto.parse !== undefined) contenuto=contenuto.parse.wikitext["*"]; else contenuto="";
	return contenuto;
	}
// esportazione in ns globale
mw.getWikitext=getWikitext;

function leggiBox(area) {
	if (area === undefined) {
		if (mw.config.get('wgCanonicalNamespace') == "Page" || $("#editBox").length===1) area = 1;
		else area = 0;
	}
	return $('textarea')[area] === undefined ? '' : $('textarea')[area].value;
}

// importazione provvisoria dello script per identificazione e parsing della pagina Indice collegata
/* importScript("MediaWiki:Gadget-currentIndex.js");function incr2(testo) {
    var r2=/\|[ —]*(\d+)[| —}];
	var npag=r2.exec(testo);
	if (npag!==null) {
		 		 testo=testo.replace(npag[0],npag[0].replace(npag[1],npag[1]*1+2));
	}
	return testo;
}
*/

// memorizza l'elemento attivo in ms.activeElement se l'elemento attivo fa parte di box di inserimento testo
// l'attivazione scatta all'evento focusin
$(document).ready(function() {
	// di default il box principale di edit
	mw.activeElement=$("#wpTextbox1")[0];
	$("textarea, input[type!='checkbox'][type!='button'][type!='search'][type!='hidden'][type!='submit'][name!='wpAntispam']").focusin(function () {
		mw.activeElement=this;
	});
});
/* vecchia funzione selection/()
function selection(area) {
	if (area === undefined) {
		if (mw.config.get("wgCanonicalNamespace") == "Page" || $("#editBox").length===1) area = 1;
		else area = 0;
	}
	var txtarea = $('textarea')[area];
	var txt = $(txtarea).val();
	var s = [];
	s[0] = txt.substring(0, txtarea.selectionStart);
	s[1] = txt.substring(txtarea.selectionStart, txtarea.selectionEnd);
	s[2] = txt.substring(txtarea.selectionEnd);
	return s;
}
*/
/* Nuova versione selection che usa mw.activeElement */
function selection(area){

	/*
	if(area===undefined){
		if(mw.config.get("wgCanonicalNamespace")=="Page"||$("#editBox").length===1)
			area=1;
		else
			area=0;
	}

	var txtarea=$('textarea')[area];
	var txt=$(txtarea).val();
	*/
	var txt=mw.activeElement.value;
	var s=[];
	s[0]=txt.substring(0,mw.activeElement.selectionStart);
	s[1]=txt.substring(mw.activeElement.selectionStart,mw.activeElement.selectionEnd);
	s[2]=txt.substring(mw.activeElement.selectionEnd);
	return s;
}


// restituisce mw.activeElement e una lista di tre stringhe che rappresentano il testo dell'elemento
// suddiviso in base alla selezione (pre, selezione, post)
function sel() {
    var elemento=mw.activeElement;
	var ss=elemento.selectionStart;
	var se=elemento.selectionEnd;
	var contenuto=elemento.value;
	var s=[contenuto.substring(0,ss),contenuto.substring(ss,se),contenuto.substring(se)];
	return [elemento, s];
}

// riscrive mw.activeElement e ristabilisce il focus/la selezione attiva
// riceve un array tipo [testo precedente, testo selezionato, testo seguente]
function scriviSel(t) {
	mw.activeElement.value=t.join("");
	mw.activeElement.selectionStart=t[0].length;
	mw.activeElement.selectionEnd= t[0].length + t[1].length;
        mw.activeElement.focus();
}
function scriviSelAlt(t) {
	mw.activeElement.value=t.join("");
	mw.activeElement.selectionStart=t[0].length + t[1].length;
	mw.activeElement.selectionEnd= t[0].length + t[1].length;
        mw.activeElement.focus();
}

// deifenatore o_O
function dehyphen() {
	scriviBox(leggiBox().replace(/([^|])[-¬] *\n([^ \n]*)[ ]*[\n]?/g,"$1$2\n"));
}

// funzione simil, tuttofare ma indispensabile a autoreCitato
function simil(s1, s2, nc) {
	if (nc === undefined) nc = 4;
	var cont1 = 0;
	for (var i = 0; i <= (s1.length - nc); i += 1) {
		if (s2.indexOf(s1.substring(i, i + nc)) != -1) cont1 += 1;
	}
	return cont1 / i;
}

function simil2(s1, s2, nc) {
	if (nc === undefined) nc = 4;
	var cont1 = 0;
	for (var i = 0; i <= (s1.length - nc); i += 1) {
		if (s2.indexOf(s1.substring(i, i + nc)) != -1) cont1 += 1;}
	for (var j = 0; j <= (s2.length - nc); j += 1) {
		if (s1.indexOf(s2.substring(j, j + nc)) != -1) cont1 += 1;
	}
	return cont1 / (i+j);
}

function piedipagina() {

	var pdp=find_stringa(testo2PagPrec[2],"{"+"{PieDiPagina","}}",1);
	var newPdp="";
	if (pdp!=="") {
		newPdp=incr2(pdp);
		if (leggiBox(2).length===0) scriviBox("<references/>",2);
		if (leggiBox(2).indexOf("{{PieDiPagina")===-1) {
				scriviBox(leggiBox(2).replace("<references/>","<references/>"+newPdp),2);
		}
	}
}
// modifico per aggiungere consensualmente eventuale tl|PNMIS
function incr2(testo) {
    var r2=/\|[ —]*(\d+)[| —}]*/;
	var npag=r2.exec(testo);
	if (npag!==null) {
 		 testo=testo.replace(npag[0],npag[0].replace(npag[1],npag[1]*1+2));
	}
	return testo;
 }

/* function newRi() {
	var currentHeader=leggiBox("0");
	// se manca un RigaIntestazione oppure esiste ma è vuoto
	if (/{{ri/i.test(currentHeader)===false || currentHeader.indexOf("{{RigaIntestazione|||}}")!==-1) {
		var header=find_stringa(testo2PagPrec[0],"/>","</noinclude>",0);

		header=newAutoRi(header);
		// se header contiene RigaIntestazione, rulla
		if (header.indexOf("{{RigaIntestazione")!==-1) scriviBox(header,"0");
	}
} */
// Nuova versione test newRi, dovrebbe gestire anche i numeri pagina in footer
function newRi() {
	var currentHeader=leggiBox("0");
	// se manca un RigaIntestazione oppure esiste ma è vuoto
	if (/{{ri/i.test(currentHeader)===false || currentHeader.indexOf("{{RigaIntestazione|||}}")!==-1) {
		var header=find_stringa(testo2PagPrec[0],"/>","</noinclude>",0);

		header=newAutoRi(header);
		// se header contiene RigaIntestazione, rulla
		if (header.indexOf("{{RigaIntestazione")!==-1) scriviBox(header,"0");
    }
    // caso PieDiPagina
    var footer="";
    if (testo2PagPrec[2].indexOf("{{PieDiPagina") !== -1) {
        var currentFooter=leggiBox(2);
        if (currentFooter.indexOf("{{PieDiPagina") ===-1) {
            currentFooter=currentFooter.replace("{{PieDiPagina","{{RigaIntestazione");
            footer=find_stringa(testo2PagPrec[2],"<noinclude>","</noinclude>",0);
            footer=footer.replace("{{PieDiPagina","{{RigaIntestazione")
            footer=newAutoRi(footer);
            if (footer.indexOf("{{RigaIntestazione")!==-1) {
                footer=footer.replace("{{RigaIntestazione", "{{PieDiPagina");
                scriviBox(footer,"2");
            }
        }
    }
}





/* function newRi() {
	var currentHeader=leggiBox("0");
	// se manca un RigaIntestazione oppure esiste ma è vuoto
	if (/{{ri/i.test(currentHeader)===false || currentHeader.indexOf("{{RigaIntestazione|||}}")!==-1) {
		var header=find_stringa(testo2PagPrec[0],"/>","</noinclude>",0);

		header=newAutoRi(header);
		// se header contiene RigaIntestazione, rulla
		if (header.indexOf("{{RigaIntestazione")!==-1) scriviBox(header,"0");
	}
    // caso PieDiPagina
    var currentFooter=leggiBox(2);
    if (currentFooter.indexOf("{{PieDiPagina") !==-1) {
        currentFooter=currentFooter.replace("{{PieDiPagina","{{RigaIntestazione")
        var footer=find_stringa(testo2PagPrec[2],"/>","</noinclude>",0);
        footer=newAutoRi(footer);
        if (footer.indexOf("{{RigaIntestazione")!==-1) {
            footer=footer.replace("{{RigaIntestazione", "{{PieDiPagina");
            scriviBox(footer,"2");
        }
    }
} */

//modifica un dato link settando il parametro par in fondo all'URL
function setURLVar(link, par, val) {
	if (link) {
		href = link.attr("href");
		if (href) {
			//rimuovi il parametro se c'era gia'
			if (href.indexOf(par) != -1) {
				regex = new RegExp(par + "=([a-z0-9]*)");
				href = href.replace(regex, "");
			}

			if (href.indexOf("?") == -1) {
				href += "?" + par + "=" + val;
			} else {
				href += "&" + par + "=" + val;
			}
			link.attr("href", href);
		}
	}
}


function scriviBox(testo, area, ss, se) {
	if (area === undefined || area === "") {
		if (mw.config.get('wgCanonicalNamespace') == "Page" || $("#editBox").length===1) {
			area = 1;
		} else {
			area = 0;
		}
	}

	//$('textarea')[area].value = testo;
	// requested by Sohom Datta for the new EIS
	$('textarea').eq(area).textSelection('setContents', testo);

	if (ss !== undefined && se !== undefined) {
		$('textarea')[area].selectionStart = ss;
		$('textarea')[area].selectionEnd = se;
	}
}

/* conta il numero di occorrenze di stringa dentro testo; esce se testo === "" oppure stringa ==="" */
function count(testo, stringa) {
	var n = 0;
	if (testo !== "" && stringa !== "") {
		while (testo.indexOf(stringa) > -1) {
			n = n + 1;
			testo = testo.replace(stringa, "");
		}
	}
	return n;
}

/*
Ricerca nella stringa testo la sottostringa che inizia con idi e termina con idf.  (idi e idf sono stringhe).

Se dc ("delimitatori compresi") è 1, restituisce la sottostringa completa di idi e idf; se dc è 0, restituisce la stringa
senza delimitatori; parametro opzionale con default 0.
Per risolvere correttamente il caso di ricerca di tag annidati, come i template, in cui l'identificatore iniziale ha una
parte non aspecifica, e una parte specifica, può essere passato un quinto parametro, che definisce  la parte aspecifica dell'identificatore iniziale.

Esempio: volendo ottenere l'intero contenuto del template {{centrato|{{sc|Testo di prova}}|l=18em}}, il risultato corretto
NON proviene dalla ricerca find_stringa("{{centrato|","}}",1), perchè sarebbe {{centrato|{{sc|Testo di prova}}.
Impostando invece find_stringa("{{centrato|","}}",1,"{{"), visto che "{{" è la parte aspecifica del primo delimitatore,
si ottiene il risultato corretto, a prescindere dal numero dei template annidati.

Se la sottostringa non viene trovata, la funzione restituisce una stringa vuota "".

*/
function find_stringa(testo, idi, idf, dc, x) {
	idip = testo.indexOf(idi);
	idfp = testo.indexOf(idf, idip + idi.length) + idf.length;
	if (idip > -1 && idfp > -1) {
		if (x !== "") {
			while (count(testo.slice(idip, idfp), x) > count(testo.slice(idip, idfp), idf)) {
				idfp = testo.indexOf(idf, idfp) + idf.length;
			}
		}
		if (dc === 0) {
			vvalore = testo.slice(idip + idi.length, idfp - idf.length);
		} else {
			vvalore = testo.slice(idip, idfp);
		}
	} else {
		vvalore = "";
	}
	return vvalore;
}

function cod(testo) {
	var l = produciLista(testo, "{"+"{", "}}", 1, "{{");
	for (var i = 0; i < l.length; i += 1) {
		testo = testo.replace(l[i], l[i].replace(/\|/g, "__!__"));
	}
	l = produciLista(testo, "[[", "]]", 1, "[[");
	for (var j = 0; j < l.length; j += 1) {
		testo = testo.replace(l[j], l[j].replace(/\|/g, "__!__"));
	}
	return testo;
}

// delim true: con delimitatori, false: senza delimitatori
function produciLista(testo, s1, s2, delim, x) {
	lista = [];
	while (find_stringa(testo, s1, s2, true, x) > "") {
		elemento = find_stringa(testo, s1, s2, true, x);
		testo = testo.replace(elemento, "");
		if (delim) {
			lista.push(elemento);
		} else {
			lista.push(elemento.slice(s1.length, - s2.length));
		}
	}
	return lista;
}

function parseTemplate(template, testo) {
	function cod(testo) {
		var l = produciLista(testo, "{"+"{", "}}", 1, "{{");
		for (var i = 0; i < l.length; i += 1) {
			testo = testo.replace(l[i], l[i].replace(/\|/g, "__!__").replace(/=/g, "__eq__"));
		}
		l = produciLista(testo, "[[", "]]", 1, "[[");
		for (i = 0; i < l.length; i += 1) {
			testo = testo.replace(l[i], l[i].replace(/\|/g, "__!__"));
		}
		return testo;
	}
	function decod(testo) {
		testo = testo.replace(/__!__/g, "|").replace(/__eq__/g, "=");
		return testo;
	}

	if (testo === undefined) testo = leggiBox();
    var cap=template.substring(0,1).toLocaleUpperCase()+template.substring(1);
    testo=testo.replace("{{"+cap,"{{"+template);
	var t = find_stringa(testo, "{"+"{" + template, "}}", 1, "{{");
	var l = []; // lista delle keys
	t = "0=" + t.substring(2, t.length - 2); // nome del template in parametro "0"
	l.push["0"];
	var ts = {};
	var n = 1;
	t = cod(t);
	t = t.split("|");

	// element for element
	for (i = 0; i < t.length; i += 1) {
		// case param is positional
		if (t[i].indexOf("=") == -1) {
			t[i] = n + "=" + t[i];
			n = n + 1;
		}
		var els = [];
		els[0] = t[i].substring(0, t[i].indexOf("=")).trim();
		els[1] = t[i].substring(t[i].indexOf("=") + 1).trim();
		if (els[1][els[1].length - 1] == "\n") els[1] = els[1].substring(0, els[1].length - 1);

		ts[els[0]] = decod(els[1]);
		l.push(els[0]);
	}

	return [ts, l];
}


function decod(testo) {
	testo = testo.replace(/__!__/g, "|");
	return testo;
}

function templateObj(nomeTemplate) {
	data = parseTemplate(nomeTemplate);
	this.keys = data[1];
	this.dict = data[0];
}

function rewriteTemplate(x,mini) {
	if (mini===undefined) mini=true;
	var testo = "";
	if (mini) {
		$.each(x[1], function (indice, valore) {
			if ((/^\d+$/).test(valore))
				testo += "|" + x[0][valore];
			else
				testo += "|" + valore + "=" + x[0][valore];
		});
		testo = "{" + "{" + testo.substring(1) + "}}";
	} else {
		$.each(x[1], function (indice, valore) {
			if (valore != "0") testo += " | " + valore + " = " + x[0][valore] + "\n";
		});
		testo = "{{" + x[0]["0"] + "\n" + testo + "}}\n";
		testo = testo.replace(/\n\s\|\s\d*\s=\s/g, "\n | ");
	}
	return testo;
}


/********************* documentazione ***********************
Lo script legge via AJAX il contenuto della pagina di cui gli viene passato il titolo e restituisce una liste di tre elementi stringa:
1. eventuale wikicode header (solo nsPagina);
2. wikicode corpo (in tutti i casi);
3. eventuale wikicode footer (solo nsPagina)

Nota:
1. i caratteri & " < > sono contenuti come html entities
2. gli spazi sono conservati come tali
3. temporaneamente viene aggiunto ai codici template e ai tag html un colore testo
*/
function acchiappaWikicode(pagina, progetto) {
	if (pagina === undefined) pagina = mw.config.get('wgPageName');
	if (progetto === undefined) {
		progetto = "";
	} else {
		progetto = "//" + progetto;
	}
	//routine non funzionante ("bug febbraio 2019")
	/*var contenuto = $.ajax({
		url: progetto + "/w/index.php?action=raw&title=" + pagina,
		async: false
	}).responseText.replace(/</g, "&lt;").replace(/>/g, "&gt;");*/
	// test nuova routine
	console.log("testo acchiappaWikicode bug febb 2109");
	var parseContenuto = JSON.parse($.ajax(
		{url: progetto+"/w/api.php?action=parse&page=" + pagina.replaceAll("&", "%26") + "&prop=wikitext&format=json",
		async: false
	}).responseText).parse;
	var contenuto = '';
	if (parseContenuto != undefined) {
		contenuto = parseContenuto.wikitext["*"].replace(/</g, "&lt;").replace(/>/g, "&gt;");
	} else {
		console.log("acchiappaWikicode: wikitesto non trovato (pagina " + pagina + " non esistente?)");
		return '';
	}

	var l = produciLista(contenuto, "{"+"{", "}}", 1, "{{");
	for (var i = 0; i < l.length; i += 1) {
		contenuto = contenuto.replace(l[i], '<span style="color: red;">' + l[i] + '</span>');
	}
	contenuto = contenuto.replace(/\&lt;/g, '<span style="color:blue">&lt;').replace(/\&gt;/g, '&gt;</span>').replace(/\n/g, "<br />");
	if (pagina.indexOf("Pagina:") != -1) {
		var noincludeList = produciLista(contenuto, '<span style="color:blue">&lt;noinclude&gt;</span>', '<span style="color:blue">&lt;/noinclude&gt;</span>', 1);
		var header = noincludeList[0];
		var footer = noincludeList[noincludeList.length - 1];
		var body = find_stringa(contenuto, header, footer, 0);
		contenuto = [header, body, footer];
	} else {
		contenuto = ["", contenuto, ""];
	}
	return contenuto;
}
mw.acchiappaWikicode=acchiappaWikicode;

function impostaBottoni(fun) {
	$(document).ready(function () {

		$('#wpSave').click(fun);
		$('#wpPreview').click(fun);
		$('#wpDiff').click(fun);
	});
}
window.impostaBottoni = impostaBottoni;

/* funzione di creazione della bottoniera
Dopo l'esecuzione, esiste #newtattoo        */
function creaBottoniera() {
	$('#' + (mw.user.options.get('skin') === 'modern' ? 'mw_' : '') + 'content')
	.append('<div id="newtattoo" align="right" style="position:fixed;bottom:0; right:0; background-color:white; border: 1px solid; border-color:#F0F0F0; z-index:1500;"></div>');
}

/* newButton accetta parametri usuali oppure un oggetto; l'oggetto deve avere questa struttura:
newButton({nome:"...", funzione:"...", azione:"...", messaggio:"...", classe:"...", stile:"...", namespaces:"..."});

Sono obbligatori solo nome, funzione, azione
Namespaces deve contenere una sequenza di namespaces (Page per Pagina), separati da | , al di fuori dei quali il bottone non sarà visualizzato; ns0 può essere indicato con Main, Principale o con uno spazio.

*/
function newButton(nome, funzione, azione, messaggio) {
// azione è una stringa composta da v,e,s,h rispettivamente view,edit,submit,history
// se nome è un oggetto svolgilo
	var p;
	if (typeof(nome) === "string") {
		p = {
			nome: nome,
			funzione: funzione,
			azione: azione,
			messaggio: messaggio
		};
	} else {
		p = nome;
	}
	if (p.messaggio===undefined) p.messaggio="Nessun aiuto registrato";
	if (p.classe===undefined) p.classe="baseButton";
	if (p.stile===undefined) p.stile="background-color: #f0f0f0; border: 1px solid #d0d0d0; padding: 3px 6px;"+
	"display: inline-block; font-size: 12px;  margin: 0;  cursor: pointer;  border-radius:4px;";
	if (p.namespaces!==undefined) {
		var listaNamespaces=p.namespaces.split("|");
		for (var i=0; i<listaNamespaces.length; i+=1) {
			listaNamespaces[i]=$.trim(listaNamespaces[i]);
			if (["ns0", "Main", "Principale"].indexOf(listaNamespaces[i]) !== -1) {
				listaNamespaces[i] === "";
			}
		}
		if ($.inArray(mw.config.get('wgCanonicalNamespace'),p.namespaces.split(","))==-1) return;
	}
// Passo 1: se newtatooo non esiste, lo crea
	if ($("#newtattoo").length===0) creaBottoniera();
	// fine se azione=history
	if (mw.config.get('wgAction') === "history") {
		return;
	}
	// normalizzazione function
	if (p.funzione.indexOf("(") === -1 && p.funzione.indexOf(")") === -1) {
		p.funzione += "()";
	}
	// default: bottone presente in view, edit,
	if (p.azione === undefined) {
		p.azione = "ves";
	}
		// messaggio di default
	if (p.messaggio === undefined) {
		p.messaggio = "Nessun messaggio di aiuto registrato";
	}
	// valutazione condizione di visualizzazione
	if (mw.config.get('wgAction') === "edit" && p.azione.indexOf("e") === -1) {
		return;
	}
	if (mw.config.get('wgAction') === "view" && p.azione.indexOf("v") === -1) {
		return;
	}
	if (mw.config.get('wgAction') === "submit" && p.azione.indexOf("s") === -1) {
		return;
	}
	// caso pulsante=immagine
	var html = "";
	if (p.nome.substring(0, 2) == "//") {
		html = '<img class="'+p.classe+'" style="'+p.stile+'" src="' + p.nome + '" onclick="' + p.funzione + '" title="' + p.messaggio +'"';
		if (p.ondblclick!==undefined) html+=' ondblclick="'+p.ondblclick+'"';
		html+='/>';
	}
	// caso pulsante=label
	else {
		html = '<button class="'+p.classe+'" style="'+p.stile+'" type="button" title="' + p.messaggio + '" onclick="' + p.funzione +'"';
		if (p.ondblclick!==undefined) html+=' ondblclick="'+p.ondblclick+'"';
		html+='><small>' + p.nome + '</small></button>';
	}
	$("#newtattoo").append($(html));
	return false;
}

function splitRiga() {
	var t=selection();
	var ps=t[2].indexOf("\n");
	var ts=t[2].substring(0,ps);
	t[2]=t[2].substring(ps)+"\n"+ts;
	scriviBox(t.join(""));
}

/**
 * http://www.openjs.com/scripts/events/keyboard_shortcuts/
 * Version : 2.01.B
 * By Binny V A
 * License : BSD
 */
var shortcut = {
	'all_shortcuts':{},//All the shortcuts are stored in this array
	'add': function(shortcut_combination,callback,opt) {
		//Provide a set of default options
		var default_options = {
			'type':'keydown',
			'propagate':false,
			'disable_in_input':false,
			'target':document,
			'keycode':false
		};
		if(!opt) opt = default_options;
		else {
			for(var dfo in default_options) {
				if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
			}
		}

		var ele = opt.target;
		if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
		var ths = this;
		shortcut_combination = shortcut_combination.toLowerCase();

		//The function to be called at keypress
		var func = function(e) {
			e = e || window.event;

			if(opt.disable_in_input) { //Don't enable shortcut keys in Input, Textarea fields
				var element;
				if(e.target) element=e.target;
				else if(e.srcElement) element=e.srcElement;
				if(element.nodeType==3) element=element.parentNode;

				if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
			}

			//Find Which key is pressed
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			var character = String.fromCharCode(code).toLowerCase();

			if(code == 188) character=","; //If the user presses , when the type is onkeydown
			if(code == 190) character="."; //If the user presses , when the type is onkeydown

			var keys = shortcut_combination.split("+");
			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
			var kp = 0;

			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
			var shift_nums = {
				"`":"~",
				"1":"!",
				"2":"@",
				"3":"#",
				"4":"$",
				"5":"%",
				"6":"^",
				"7":"&",
				"8":"*",
				"9":"(",
				"0":")",
				"-":"_",
				"=":"+",
				";":":",
				"'":"\"",
				",":"<",
				".":">",
				"/":"?",
				"\\":"|"
			};
			//Special Keys - and their codes
			var special_keys = {
				'esc':27,
				'escape':27,
				'tab':9,
				'space':32,
				'return':13,
				'enter':13,
				'backspace':8,

				'scrolllock':145,
				'scroll_lock':145,
				'scroll':145,
				'capslock':20,
				'caps_lock':20,
				'caps':20,
				'numlock':144,
				'num_lock':144,
				'num':144,

				'pause':19,
				'break':19,

				'insert':45,
				'home':36,
				'delete':46,
				'end':35,

				'pageup':33,
				'page_up':33,
				'pu':33,

				'pagedown':34,
				'page_down':34,
				'pd':34,

				'left':37,
				'up':38,
				'right':39,
				'down':40,

				'f1':112,
				'f2':113,
				'f3':114,
				'f4':115,
				'f5':116,
				'f6':117,
				'f7':118,
				'f8':119,
				'f9':120,
				'f10':121,
				'f11':122,
				'f12':123
			};

			var modifiers = {
				shift: { wanted:false, pressed:false},
				ctrl : { wanted:false, pressed:false},
				alt  : { wanted:false, pressed:false},
				meta : { wanted:false, pressed:false}	//Meta is Mac specific
			};

			if(e.ctrlKey)	modifiers.ctrl.pressed = true;
			if(e.shiftKey)	modifiers.shift.pressed = true;
			if(e.altKey)	modifiers.alt.pressed = true;
			if(e.metaKey)   modifiers.meta.pressed = true;

			for(var i=0; k=keys[i],i<keys.length; i++) {
				//Modifiers
				if(k == 'ctrl' || k == 'control') {
					kp++;
					modifiers.ctrl.wanted = true;

				} else if(k == 'shift') {
					kp++;
					modifiers.shift.wanted = true;

				} else if(k == 'alt') {
					kp++;
					modifiers.alt.wanted = true;
				} else if(k == 'meta') {
					kp++;
					modifiers.meta.wanted = true;
				} else if(k.length > 1) { //If it is a special key
					if(special_keys[k] == code) kp++;

				} else if(opt.keycode) {
					if(opt.keycode == code) kp++;

				} else { //The special keys did not match
					if(character == k) kp++;
					else {
						if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
							character = shift_nums[character];
							if(character == k) kp++;
						}
					}
				}
			}

			if(kp == keys.length &&
						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
						modifiers.shift.pressed == modifiers.shift.wanted &&
						modifiers.alt.pressed == modifiers.alt.wanted &&
						modifiers.meta.pressed == modifiers.meta.wanted) {
				callback(e);

				if(!opt['propagate']) { //Stop the event
					//e.cancelBubble is supported by IE - this will kill the bubbling process.
					e.cancelBubble = true;
					e.returnValue = false;

					//e.stopPropagation works in Firefox.
					if (e.stopPropagation) {
						e.stopPropagation();
						e.preventDefault();
					}
					return false;
				}
			}
		}
		this.all_shortcuts[shortcut_combination] = {
			'callback':func,
			'target':ele,
			'event': opt['type']
		};
		//Attach the function with the event
		if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
		else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
		else ele['on'+opt['type']] = func;
	},

	//Remove the shortcut - just specify the shortcut and I will remove the binding
	'remove':function(shortcut_combination) {
		shortcut_combination = shortcut_combination.toLowerCase();
		var binding = this.all_shortcuts[shortcut_combination];
		delete(this.all_shortcuts[shortcut_combination])
		if(!binding) return;
		var type = binding['event'];
		var ele = binding['target'];
		var callback = binding['callback'];

		if(ele.detachEvent) ele.detachEvent('on'+type, callback);
		else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
		else ele['on'+type] = false;
	}
}
/*Chiamata senza parametri corregge gli apostrofi nel box di default (wpTextbox1[0] in ns0, wpTextbox1[1] in nsPagina.
In rari casi può essere forzata l'azione su un box non di default (box="0","1","2" ) */
function newApostrofi(box) {
	var testo;
	if (box === undefined) {
		testo = leggiBox();
	} else {
		testo = leggiBox(box);
	}
	var testoCod = codifica(testo);
	testoCod[0] = testoCod[0].replace(/'/g, '’').replace(/’’’’’/g, "'''''").replace(/’’’’/g, "''''").replace(/’’’/g, "'''").replace(/’’/g, "''");
	testo = decodifica(testoCod[0], testoCod[1]);
	if (box === undefined) {
		scriviBox(testo);
	} else {
		scriviBox(testo, box);
	}
}
// funzione per gestire l'icona Link a immagini IA in nsIndice
$(document).ready(function () {
	if (mw.config.get('wgCanonicalNamespace')=="Index") {
		var dataIA=$("span.data").data("fonte");

		if (dataIA !== undefined) {
			if (dataIA.indexOf("[")==-1) {
				iaItem=find_stringa(dataIA+"/","/details/","/",0); //prendi cio' che si trova tra /details/ e il successivo /
			}
			else {
				iaItem=find_stringa(dataIA,"/details/"," ",0);     //prendi cio' che si trova tra /details/ e il successivo spazio
			}
			if (iaItem!=="") {     // fonte contiene un link come stringa
				iaImageLink="//archive.org/download/"+iaItem+"/"+iaItem+"_jp2.zip/";
				$("div[title='IA HR images link'] a").attr("href",iaImageLink).removeClass("image").attr("target","_blank");
			}
			else {
				$("div[title='IA HR images link']").remove();
			}
		}
	}
});

//  scrive una pagina generica
//  dati è un oggetto:
//  dati.nome
//  dati.testo
//  dati.sommario
function pagePut(dati) {

    if(dati.nome===undefined || dati.sommario===undefined || dati.testo===undefined) {
    	alert("parametri pagePut insufficienti");
    	return;
    }
	$.ajax({
    	url: mw.util.wikiScript( 'api' ),
    	data: {
        	format: 'json',
        	action: 'edit',
        	title: dati.nome,
        	summary: dati.sommario,
        	text: dati.testo,
        	token: mw.user.tokens.get('csrfToken')
    	},
    	dataType: 'json',
    	type: 'POST',
    	success: function( data ) {

    		if ( data && data.edit && data.edit.result == 'Success' ) {

				if (dati.reload)  window.open(window.location.origin+window.location.pathname+"?action=purge","_self");
				                                                      // purges current page
				if (dati.messaggio) mw.notify(messaggio);
				if (dati.feedback) alert(dati.feedback);

    		} else if ( data && data.error ) {
    			alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
			} else {
    			alert( 'Error: Unknown result from API.' );
			}
		},
		error: function( xhr ) {
			alert( 'Error: Request failed.' );
		}
	});
}

function pageGet(pagina) {
	if (pagina===undefined) pagina=mw.config.get("wgPageName");
	var contenuto = $.ajax({
	url: "/w/index.php?action=raw&title=" + pagina,
	async: false
	}).responseText;
	return contenuto;
}

// template è il nome del template di cui fare il parsing (es. RigaIntestazione )
// testo è il testo dove ricercare il template (default leggiBox() )
// restituisce un oggetto costituito da un dizionario e una lista
// il dizionario contiene le coppie nome paramtro - valore
// la lista contiene i nomi dei parametri, o cifre (in stringa) per i parametri posizionali
// il nome del template è associato al parametro con chiave "0" )
// esempio: da Pagina:Eneide (Caro).djvu/91 ilcomando:
// parseTemplate("RigaIntestazione",leggiBox(0))
// restituisce [{"0":"RigaIntestazione","1":"48","2":"{{Sc|l'eneide.}}","3":"[1158-1182]"},["0","1","2","3"]]






/***************
La funzione codifica() riceve un testo markup wiki e restituisce un testo "puro" e una lista ordinata degli elementi
che vanno protetti da replace() pena l'interruzione di link ecc.

ATTENZIONE: funzione in fase di test

**************/

function codifica(testo) {
	var l = [];
	// gestione poem
    var poem="";
    var lista=produciLista(testo,"{" + "{poem","}}",1,"{{")
    if (lista.length>0) {
        for (i=0;i<lista.length;i+=1) {
            poem=lista[i].replace("{" + "{poem","<#poem>").replace(/}}$/,"</#poem>")
            testo=testo.replace(lista[i],poem)
        }
    }
    // fine gestione poem
	var res = ss(testo, l, "<math", "</math>", "");
	res = ss(res[0], res[1], "<!--", "-->", "<");
	res = ss(res[0], res[1], "{", "}", "{");
	res = ss(res[0], res[1], "[", "]", "[");
	res = ss(res[0], res[1], "<", ">", "<");
	res = ss(res[0], res[1], "http://", " ", "");
	res = ss(res[0], res[1], "https://", " ", "");
	return res;
}

function ss(testo, l, tagi, tagf, x) {
	while (find_stringa(testo, tagi, tagf, 1) > "") {
		var el = find_stringa(testo, tagi, tagf, 1, tagi);
		testo = testo.replace(el, "###el" + l.length + "###");
		l.push(el);
	}
	return [testo, l];
}

// La funzione decodifica() riceve un testo codificato e la lista degli elementi protetti e restituisce un testo
// con gli elementi protetti risistemati al loro posto; è complementare a codifica()
function decodifica(testo, l) {
	for (i = l.length - 1; i > -1; i = i - 1) {
		testo = testo.replace("###el" + i + "###", l[i]);
	}
	// gestione poem
	testo=testo.replace(/<#poem>/g,"{{poem").replace(/<\/#poem>/g,"}}");
return testo;
}

//Sostituisce tutti gli apostrofi dattilografici in tipografici, ma rispetta gli apostrofi di marckup wiki e gli apostrofi
//contenuti in: math, {{{}}}, {{}}, [[]], [], http:.....
function apostrofi(editbox) {
	if (editbox === undefined) {
		editbox = document.getElementsByName('wpTextbox1')[0];
	}
	var testoCod = codifica(editbox.value);
	testoCod[0] = testoCod[0].replace(/'/g, '’').replace(/’’’’’/g, "'''''").replace(/’’’’/g, "''''").replace(/’’’/g, "'''").replace(/’’/g, "''");
	editbox.value = decodifica(testoCod[0], testoCod[1]);
}

function autoPt() {

	var t = [],
	rFin = /\ (\w+’*\w+)-$/,			// parola finale ifenata
	rPtIniz = /^\{\{pt\|/i,		// pt in testa sulla pagina corrente
	rPtFin = /\{\{pt\|(.+)-\|\}\}/i,	// pt di tipo finale
	rHyp2 = /^[^ \n]+/,
	hyp = "",
	hyp2 = "",
	l = [],
	prePt = "",
	headTxt="",
	rht=/^(({{nop}})*\n*)/;
		t = selection();
	// se c'è una selezione di testo....
	if (t[1].length > 0) {
		if (t[0].length > t[2].length) { //allora va applicato un pt-before...
			t[1] = "{{Pt|" + t[1] + "|}}";

		} else {
			testoPagPrec[1] = testoPagPrec[1].replace(/\{\{pt\|/g, "{{Pt|");
			l = produciLista(testoPagPrec[1], "{{Pt|", "}}", 1, "{{");
			prePt = "";
			if (l.length > 0) {
				prePt = l[l.length - 1];
				prePt = find_stringa(prePt, "{{Pt|", "|", 0);
			}
			t[1] = "{{Pt|" + t[1] + "|" + prePt.substring(0, prePt.length - 1) + t[1] + "}}";
		}
		scriviSel(t);
	} else {// invece se non c'è alcuna selezione di testo...
		t = leggiBox();
		headTxt=rht.exec(t)[0];
		if (t.indexOf("{{nop}}")==0) t=t.replace("{{nop}}","");
		t=$.trim(t);
		// se la pagina precedente ha un pt di tipo finale
		// e la pagina corrente non ha un pt di tipo iniziale
		// allora applica un pt iniziale
		if (rPtFin.exec(testoPagPrec[1]) !== null && rPtIniz.exec(t) === null) {
			hyp = rPtFin.exec(testoPagPrec[1])[1];
			hyp2 = rHyp2.exec(t);
			t = "{{Pt|" + hyp2 + "|" + hyp + hyp2 + "}}" + t.replace(hyp2, "");
		}
		// se la pagina corrente termina con parola ifenata
		// allora applica pt finale sulla
		if (rFin.exec(t) !== null) {
			hyp = rFin.exec(t)[1]; //parola ifenata senza trattino
			t = t.substr(0, t.search(rFin) + 1) +
				"{{Pt|" + hyp + "-|}}";
		}
	scriviBox(headTxt+t);}
}

function refs() {
	tt=selection();

	t=tt[1].split("\n");
	for (i=0;i<t.length;i+=1){
		if ($.trim(t[i])!=="") t[i]="<ref>"+t[i]+"</ref>";
	}
	tt[1]=t.join("\n");
	scriviBox(tt.join(""));
}

/*
incapsula = function(pre, post) {
		mw.toolbar.insertTags(pre,post);
	};
*/
incapsula=function(pre,post,hl) {
    if (hl===undefined) hl=false;
    var selezione=sel();var sct=selezione[0].scrollTop;
    while (selezione[1][1].slice(-1)==" ") {
    selezione[1][1]=selezione[1][1].slice(0,-1);
    selezione[1][2]=" "+selezione[1][2];
    }
    selezione[1][1]=pre+selezione[1][1]+post;
    $(selezione[0]).val(selezione[1].join(""));

    selezione[0].selectionEnd=selezione[1][0].length+selezione[1][1].length;
    if (hl)
        selezione[0].selectionStart=selezione[1][0].length;
    else
        selezione[0].selectionStart=selezione[0].selectionEnd;
    selezione[0].focus(); // selezione[0].scrollTop=sct;
    return;
};
// funzione per modificare eis preview se esiste in risposta a tools RegexMenuFramework ed altri
function updatePreview() {
	if ($("#divPreview").length===1 && $("#divPreview").css("display")==="block") mw.pagePreview();
}
// elenco di variabili che funzionano correttamente solo se sono definite come globali
window.shortcut=shortcut;
window.newButton=newButton;
window.sel=sel;
window.scriviSel=scriviSel;
window.scriviSelAlt=scriviSelAlt;
window.scriviBox=scriviBox;
window.acchiappaWikicode=acchiappaWikicode;
window.newRi=newRi;
window.autoPt=autoPt;
window.produciLista=produciLista;