Järjestelmäviesti:Gadget-Tekstileikkeet-testi.js
Huomautus: Selaimen välimuisti pitää tyhjentää asetusten tallentamisen jälkeen, jotta muutokset tulisivat voimaan.
- Firefox ja Safari: Napsauta Shift-näppäin pohjassa Päivitä, tai paina Ctrl-F5 tai Ctrl-R (⌘-R Macilla)
- Google Chrome: Paina Ctrl-Shift-R (⌘-Shift-R Macilla)
- Internet Explorer ja Edge: Napsauta Ctrl-näppäin pohjassa Päivitä tai paina Ctrl-F5
- Opera: Paina Ctrl-F5.
/**
* Gadget-Tekstileikkeet 0.999
**/
/**
* Koodimoduulien yhteiset osat.
**/
(function () {
window.Leikkeet2 = {};
/**
* Ohjesivun osoite.
**/
Leikkeet2.helpUrl = "//fi.wiktionary.org/w/Ohje:Gadget-Tekstileikkeet";
/**
* Käyttäjän oman hallintasivun nimi.
**/
Leikkeet2.getManagePageTitle = function () {
return mw.config.get("wgUserName") + "/" + "Gadget-Tekstileikkeet";
};
/**
* Käyttäjän oman hallintasivun url.
**/
Leikkeet2.getManagePageUrl = function () {
return '//fi.wiktionary.org/wiki/Käyttäjä:' +
encodeURIComponent(mw.config.get("wgUserName")) + "/" + "Gadget-Tekstileikkeet";
};
Leikkeet2.encodeSnippetContent = function (txt) {
txt = txt.replace(/⦃/g, "{{{");
txt = txt.replace(/⦄/g, "}}}");
txt = txt.replace(/∷/g, "|");
return txt;
};
/**
* Palauttaa taulukon, jossa on tekstin txt kaikki parametrinimet (esim. "{{{1|}}}"). Taulukko
* on muotoa [a, l, t], jossa
* a = alkuindeksi
* l = loppuindeksi
* t = {- ja }-merkkien määrä kutsussa. Mallineilla 2, parametreilla 3, mutta voi olla
* myös suurempi arvo, jos kutsuja on monta sisäkkäin.
*/
function getEncodedParams(txt) {
/**
* Usean {- tai }-merkin ryppäät. Rypäs on yhteinäinen jono {-, }-, [- tai ]-merkkejä.
* Muotoa [a, l, t, p], jossa
* a = alkuindeksi
* l = loppuindeksi
* t = tyyppi ('{' tai '}')
*/
var ryppaat = [];
var result;
var alku = 0;
/*
* Etsitään ryppäät tekstistä. Ohitetan yksittäiset {- ja }-merkit.
*/
var pat = /(\{\{+|\}\}+|\[\[|\]\])/;
while ( (result = pat.exec(txt.substring(alku))) !== null ) {
var a = result.index;
var l = a + result[0].length;
ryppaat.push([alku+a, alku+l, result[0][0]]);
alku += l;
}
var mkutsut = [];
/**
* Ohitetut ryppäät. Vastaan tulevat '{'-merkkiset ryppäät siirretään pinoon, josta
* niitä vähennetään vastaan tulevilla '}'-ryppäillä.
**/
var pino = [];
pino.top = function (v) {
if ( v !== undefined ) {
pino[pino.length-1] = v;
}
return pino[pino.length-1];
};
ryppaat.first = function (v) {
if ( v !== undefined ) {
ryppaat[0] = v;
}
return ryppaat[0];
};
/**
* Tallennetaan parametrit ja ohitetaan mallineet ja linkit.
* Param v on ryppaat taulukon rivi.
*/
function tallenna(v) {
if ( v[2] == 3 && v[3] == '{' ) {
mkutsut.push(v);
}
}
/*
* Otetaan jonosta ryväs, jos se on {-merkkinen, siirretään pinoon. Jos }-merkkinen
* vähennetään pinossa olevista {-merkeistä.
*/
while ( ryppaat.first() !== undefined ) {
var k = ryppaat.first();
ks = k[0];
ke = k[1];
km = k[2];
var kl = ke - ks;
if ( km == '{' || km == '[' ) {
pino.push(ryppaat.shift());
} else { /* km == '}' || km == ']' */
if ( pino.top() === undefined ) { break; }
var t = pino.top();
var ts = t[0];
var te = t[1];
var tm = t[2];
var tl = te - ts;
if ( tm == "[" && km == "}" ) {
ryppaat.shift(); // ohitetaan pariton '}'
} else if ( tm == "{" && km == "]" ) {
pino.pop(); // ohitetaan pariton '{'
} else { // joko {}- tai []-parit
if ( kl == tl ) {
tallenna([ts, ke, tl, tm]);
pino.pop();
ryppaat.shift();
} else if ( kl < tl ) {
tallenna([te - kl, ke, kl, tm]);
te = te - kl;
+ pino.top([ts, te, tm]);
ryppaat.shift();
if ( te - ts == 1 ) { // ohitetaan yksittäiset jäljelle jääneet
pino.pop();
}
} else if ( tl < kl ) {
tallenna([ts, ks + tl, tl, tm]);
ks += tl;
ryppaat.first([ks, ke, km]);
pino.pop();
if ( ke - ks == 1 ) { // ohitetaan yksittäiset jäljelle jääneet
ryppaat.shift();
}
}
}
}
}
return mkutsut;
}
/**
* Dekoodaa {{{1|kana}}}-tyyppiset ⦃1∷kana⦄-tyyppisiksi.
**/
function decodeParameters(txt, mkutsut) {
var start = 0;
var out = [];
var i;
for ( i in mkutsut ) {
// ohitetaan sisäkkäiset
if ( start > mkutsut[i][0] ) {
console.log("Sisäkkäiset kentät");
continue;
}
out.push(txt.substring(start, mkutsut[i][0]));
out.push(txt.substring(mkutsut[i][0], mkutsut[i][1])
.replace(/^{{3}0}{3}$/, "⦃∷⦄")
.replace(/^{{3}/, "⦃")
.replace(/\|/, "∷")
.replace(/}{3}$/, "⦄"));
start = mkutsut[i][1];
}
out.push(txt.substring(start, txt.length));
return out.join("");
}
Leikkeet2.decodeSnippetContent = function(txt) {
return decodeParameters(txt, getEncodedParams(txt));
};
Leikkeet2.encodeSnippets = function (groupList) {
return groupList.map(function (group) {
return {
name: group.name,
list: group.list.map(function (snippet) {
return {
key : snippet.key,
content : Leikkeet2.encodeSnippetContent(snippet.content) };
})};
});
};
Leikkeet2.decodeSnippets = function (groupList) {
return groupList.map(function (group) {
return {
name: group.name,
list: group.list.map(function (snippet) {
return {
key : snippet.key,
content : Leikkeet2.decodeSnippetContent(snippet.content) };
})};
});
};
/**
* Tallentaa leikkeet localstorageen.
*
* @param groupList: ryhmän mukaan järjestetty lista listoista.
**/
Leikkeet2.saveSnippetTree = function(groupList) {
localStorage.setItem('tekstileikkeet', JSON.stringify(groupList));
};
/**
* Lataa leikkeet localstoragesta.
*
* @return: ryhmän mukaan järjestetty lista listoista.
**/
Leikkeet2.loadSnippetTree = function() {
var dataStr = localStorage.getItem('tekstileikkeet');
var groupList = null;
try {
groupList = JSON.parse(dataStr);
} catch ( e ) {
alert("leikkeitä ei voitu lukea: " + e);
return null;
}
return groupList;
};
/**
* Palauttaa leikkeet dictinä, jossa avaimena on snippetin nimi.
*
* Alkio on leikkeen sisältö. TODO pois
*
* @param groupList: ryhmän mukaan järjestetty lista leikelistoista.
**/
Leikkeet2.getSnippets = function() {
var groupList = Leikkeet2.loadSnippetTree();
var i, j;
var group;
var snippet;
var snippets = {};
for ( i in groupList ) {
group = groupList[i];
for ( j in group.list ) {
snippet = group.list[j];
//snippet.group = group.name;
snippets[snippet.key] = snippet.content;
}
}
return snippets;
};
/**
* Palauttaa leikkeet dictinä, jossa avaimena on snippetin nimi.
*
* Alkiot ovat muotoa { "key" : "", "content" : "", "group : "" }.
*
* @param groupList: ryhmän mukaan järjestetty lista leikelistoista.
**/
Leikkeet2.getSnippetDict = function() {
var groupList = Leikkeet2.loadSnippetTree();
var i, j;
var group;
var snippet;
var snippets = {};
for ( i in groupList ) {
group = groupList[i];
for ( j in group.list ) {
snippet = group.list[j];
snippets[snippet.key] = {
"key" : snippet.key,
"group" : group.name,
"content" : snippet.content,
"index" : j };
}
}
return snippets;
};
})();
/**
* Leikkeiden korvaamista tekstilaatikossa käsittelevä koodi.
**/
(function(){
var Wikileike = {
leikkeet: null
};
/**
* Merkit, joihin haku katkeaa kun etsitään leikekutsun alkukohtaa, ts. merkit jotka eivät
* voi kuulua leikeviitteeseen.
**/
var KATKOMERKIT = " \n\t:∷⦃⦄|*#;";
/**
* Merkki, joka katkaisee leikeviitteen, mutta jota ei lueta viitteen nimeen.
**/
var ALKUMERKKI = "$";
var $textbox;
/**
* Koodissa käytettyjä termejä:
* leike: koostuu leikenimestä ja leiketekstistä
* leikenimi: nimi, jolla teittyyn leikkeeseen viitataan
* leiketeksti: leikken sisältämä teksti, jolla leikeviite korvataan
* leikeviite: tekstissä esiintyvä leikenimi
* kenttä: leiketekstissä oleva kenttä, jolle voi antaa arvon;
* tekstissä joko muotoa ⦃1⦄ tai ⦃1∷arvo⦄, vastaavasti TODO leikesivulla
* muotoa {{{1}}} ja {{{1|arvo}}}; kenttiin viitataan niiden alku- ja
* loppukohtien indekseillä, esim. [2, 4].
* sisäkenttä: kentän ∷- ja ⦄-merkkien väli, ei sisällä itse merkkejä
* ulkokenttä: kentän ⦃- ja ⦄-merkkien väli, mukaan lukien itse merkit
* kentän otsikko-osa: kentän ⦃- ja ∷-merkkien väli.
* kentän otsikko: kentän otsikko-osan teksti
*
**/
/**************************
* Ulos näkyvät funktiot. *
**************************/
/**
* Korvaa valitun tekstin tai kursoria edeltävän tekstin sitä
* vastaavalla leikkeellä, jos sellainen on.
**/
Wikileike.laajenna_leike = function() {
var pcur = sel.hae_kohdat();
var pviit = [];
var text = $textbox.val();
var pos = sel.hae_alku();
var nykykentta = hae_sisin(0, text, pos);
// Jos tekstiä on valittu yritetään laajentaa valittu teksti, muuten
// etsitään edellinen leikeviittauksen nimessä sallimaton merkki ja
// valitaan siitä kursorin paikkaan asti.
if ( pcur[0] == pcur[1] ) {
pviit[0] = hae_viittauksen_alku(text, pcur[0]);
pviit[1] = pcur[0];
sel.valitse(pviit[0], pcur[0]);
} else {
if ( pcur[0] < pcur[1] ) {
pviit = pcur;
} else {
pviit[0] = pcur[1];
pviit[1] = pcur[0];
}
}
var snippetti = sel.hae_valinta();
if ( snippetti[0] == ALKUMERKKI ) { snippetti = snippetti.substring(1); }
var leike = Wikileike.leikkeet[snippetti];
if ( leike === undefined ) {
console.log("Tuntematon leike: " + snippetti);
// Jätetään valinta päälle.
return;
}
console.log("leike: " + JSON.stringify(leike));
leike = leike.replace(/⦃([^∷]*?)⦄/g, "⦃$1∷⦄", leike);
setTimeout(function() {
// Jos snippetti löytyy, korvataan valinta, muuten vain poistetaan
// valinta ja siirrytään sen loppuun.
if ( leike ) {
sel.korvaa(leike, false);
// Tutkitaan onko leikkeessä kenttiä. Jos on, siirrytään ekaan
// kenttään. Jos ei, siirrytään snippetin loppuun.
var ekakentta = eka_kentta(leike, 0);
if ( ekakentta ) {
console.log("eka kenttä:", JSON.stringify(ekakentta) );
var sekakentta = Wikileike.hae_sisakentta(leike,
ekakentta);
console.log("s-eka kenttä:", JSON.stringify(sekakentta) );
sel.valitse(pviit[0] + sekakentta[0], pviit[0]
+ sekakentta[1]);
// Jos eka kenttä on nollakenttä, suljetaan samantien.
if ( ekakentta[2] == "" ) {
Wikileike.hyppaa_seuraavaan();
}
} else {
sel.siirry(pviit[0] + leike.length);
}
} else {
sel.siirry(pcur[0]);
}
}, 100);
};
/**
* Siirry seuraavaan kenttään tai sulje kenttä yläkenttä.
*/
Wikileike.hyppaa_seuraavaan = function() {
var text = $textbox.val();
var pos = sel.hae_alku();
// Haetaan nykyinen kenttä, eli kenttä jossa kursori on.
var nykykentta = hae_sisin(0, text, pos);
// Jos ollaan ylimmällä tasolla.
if ( nykykentta[0] == -1 ) return;
var nykykentta_nimi = Wikileike.hae_kentan_otsikko(text, nykykentta);
var nykykentta_s = Wikileike.hae_sisakentta(text, nykykentta);
var nykykentta_arvo = text.substring(nykykentta_s[0], nykykentta_s[1]);
var ylakentta = hae_ylakentta(text, nykykentta);
// Etsitään samannimiset kentät ja korvataan niiden sisältö saadulla
// kentän sisällöllä.
aseta_kentat_arvoon(text, ylakentta, nykykentta[1], nykykentta_nimi,
nykykentta_arvo);
// Päivitetään muuttunut teksti. Nykykenttä on kutenkin sama,
// ylakenttä ei.
text = $textbox.val();
// Haetaan seuraava kenttä.
seurkentta = hae_sisarkentta(text, nykykentta, +1);
// Siirrytään seuraavaan kenttään. Jos seuraavaa kenttää ei ole tai
// se on nollakenttä, suljetaan yläkenttä.
if ( seurkentta ) {
console.log("seurkentta:", JSON.stringify(seurkentta));
var sisakentta = Wikileike.hae_sisakentta(text, seurkentta);
sel.valitse(sisakentta[0], sisakentta[1]);
if ( seurkentta[2] == "" ) {
setTimeout(function() {
ylakentta = hae_ylakentta(text, nykykentta);
sulje_kentta(text, ylakentta, sel.hae_loppu());
}, 100);
}
} else {
ylakentta = hae_ylakentta(text, nykykentta);
sulje_kentta(text, ylakentta, sel.hae_loppu());
}
};
/**
* Siirry edelliseen kenttään.
**/
Wikileike.hyppaa_edelliseen = function() {
var text = $textbox.val();
var pos = sel.hae_alku();
// Haetaan kenttä, jossa kursori on.
var nykykentta = hae_sisin(0, text, pos);
// Haetaan edellinen kenttä.
var edkentta = hae_sisarkentta(text, nykykentta, -1);
// Siirrytään edelliseen kenttään, jos sellainen on, muuten ei tehdä
// mitään.
if ( edkentta ) {
var edkentta_s = Wikileike.hae_sisakentta(text, edkentta);
sel.valitse(edkentta_s[0], edkentta_s[1]);
}
};
/**
* Palauttaa viittauksen otsikko-osan alku- ja loppukohdan.
* Esim. "⦃3∷oletusarvo⦄" -> [1,2].
**/
Wikileike.hae_kentan_otsikkoOsa = function(text, kentta) {
if ( kentta.otsikkoOsa !== undefined ) return kentta.otsikkoOsa;
var a = kentta[0], l = kentta[1];
// Uloin taso.
if ( a == -1 ) {
kentta.otsikkoOsa = [a, a];
return kentta.otsikkoOsa;
}
// Etsitään mahdollinen ensimmäinen sisäinen alkava viite, ettei
// vahingossa lueta sen ∷-merkkiä.
var raja = text.indexOf("⦃", a+1);
if ( raja == -1 || raja > l ) { raja = l; }
var p = text.indexOf("∷", a+1);
if ( p != -1 && p < raja ) {
kentta.otsikkoOsa = [a+1, p];
return kentta.otsikkoOsa;
}
// Ei parametriosaa.
kentta.otsikkoOsa = kentta;
return kentta;
};
/**
* Hae sisäkentän otsikon teksti.
* Viite on muotoa ⦃otsikko∷sisäkenttä⦄.
* Esim. ⦃3∷oletusarvo⦄ -> 3.
*/
Wikileike.hae_kentan_otsikko = function(text, kentta) {
var pp = Wikileike.hae_kentan_otsikkoOsa(text, kentta);
if ( pp ) {
return text.substring(pp[0], pp[1]);
}
return null;
};
/**
* Hakee kentan parametriosan ääripäät.
* Ts. "∷"- ja "⦄"-merkin tai "⦃"- ja "⦄"-merkin välin.
* Esim. "⦃3∷oletusarvo⦄" -> [3,11].
* Olettaa, että text[a] == "⦃" ja text[l] == "⦄" eikä ⦃ ja ∷-merkin
* välissä ole muita hakasulkumerkkejä.
* Viitteet voivat olla muodossa ⦃sisäkenttä⦄ tai ⦃otsikko∷sisäkenttä⦄.
* Num-osassa ei saa olla muita viitteitä.
*/
Wikileike.hae_sisakentta = function(text, kentta) {
var a = kentta[0], l = kentta[1];
if ( kentta.sisakentta === undefined ) {
// Jos kyseessä on koko teksti, on sisäkenttä myös koko teksti.
if ( a == -1 && l == text.length+1 ) {
kentta.sisakentta = [a+1, l-1];
} else {
var oo = Wikileike.hae_kentan_otsikkoOsa(text, kentta);
assert ( oo !== null, "hae_sisakentta: Kenttä ilman otsikko-osaa!" );
kentta.sisakentta = [oo[1]+1, l-1];
}
}
return kentta.sisakentta;
};
/**********************
* Sisäiset funktiot. *
**********************/
function assert(ehto, viesti) {
if ( !ehto ) {
alert("ASSERT-VIRHE: " + viesti);
}
}
/**
* Lyhenteet textSelectionin metodeille.
*/
var sel = {
valitse: function(alku, loppu) {
if ( loppu === undefined ) { loppu = alku; }
$textbox.textSelection('setSelection',
{ 'start': alku, 'end': loppu });
},
siirry: function(kohta) {
$textbox.textSelection('setSelection',
{ 'start': kohta, 'end': kohta });
},
hae_valinta: function() {
return $textbox.textSelection('getSelection');
},
/**
* Palauttaa valinnan alku- ja loppukohdat taulukkona.
*/
hae_kohdat: function() {
return $textbox.textSelection('getCaretPosition',
{ 'startAndEnd' : true });
},
/**
* Palauttaa valinnan pelkän alkukohdan.
*/
hae_alku: function() {
return $textbox.textSelection('getCaretPosition',
{ 'startAndEnd' : false });
},
hae_loppu: function() {
var ppos = sel.hae_kohdat();
return ppos[1];
},
korvaa: function(teksti, valitse) {
var ppos = sel.hae_kohdat();
var spos = ppos[0];
var epos = ppos[1];
//var text = $textbox.val();
$textbox.textSelection('replaceSelection', teksti);
//$textbox.val(text.substring(0, spos) + teksti
// + text.substring(epos, text.length));
epos = spos + teksti.length;
if ( valitse ) {
sel.valitse(spos, epos);
$textbox.focus();
}
}
};
/**
* Palauttaa leike-kutsun alkukohdan.
**/
function hae_viittauksen_alku(text, pos) {
for ( var i = pos-1; i >= 0; i-- ) {
if ( text[i] == ALKUMERKKI ) {
return i;
} else if ( KATKOMERKIT.indexOf(text[i]) != -1 ) {
return i+1;
}
}
return 0;
}
function hae_seuraava(tasap, teksti, pos, asti) {
var tp = 0;
if ( asti === undefined ) { asti = teksti.length; }
for (var i = pos; i < asti; i++ ) {
if ( teksti[i] == '⦃' ) {
tp++;
} else if ( teksti[i] == '⦄' ) {
tp--;
// Ei mieltä jatkaa jos menee alle perustason.
if ( tp < 0 && tasap == +1 ) { return -1; }
}
if ( tp == tasap ) {
return i;
}
}
return -1;
}
function hae_edellinen(tasap, teksti, pos, asti) {
var tp = 0;
if ( asti === undefined ) { asti = 0; }
for (var i = pos-1; i >= asti; i-- ) {
if ( teksti[i] == '⦃' ) {
tp++;
// Ei mieltä jatkaa jos menee alle perustason.
if ( tp > 0 && tasap == -1 ) { return -1; }
} else if ( teksti[i] == '⦄' ) {
tp--;
}
if ( tp == tasap ) {
return i;
}
}
return -1;
}
/**
* Laskee positiota 'pos' vastaavan uuden position 'taulukoi'-funktion
* tekemässä taulukossa 'kentät', kun kenttämerkit on poistettu.
*/
function laske_uusi_pos(kentat, pos) {
var upos = 0, vpos = 0;
for ( var e in kentat ) {
var ulen = kentat[e][4] - kentat[e][3];
var vlen = kentat[e][2] - kentat[e][1];
upos += (kentat[e][1] - vpos);
if ( kentat[e][1] >= pos ) {
return upos + (pos - vpos);
} else if ( kentat[e][3] >= pos ) {
return upos;
} else {
if ( kentat[e][4] >= pos ) {
return upos + (pos - kentat[e][3]);
} else if ( kentat[e][2] >= pos ) {
return upos + ulen;
}
}
upos += ulen;
vpos = kentat[e][2];
}
return upos;
}
/**
* Poistaa kenttämerkit ja korvaa kentät niiden sisällöllä.
*/
function poista_kentat(text, kentat) {
var upos = 0;
var a = 0, text_o = [];
for ( var e in kentat ) {
var sisalto = text.substring(kentat[e][3], kentat[e][4]);
text_o.push(text.substring(a, kentat[e][1]) + sisalto);
a = kentat[e][2];
}
text_o.push(text.substring(a));
return text_o.join("");
}
/**
* Poistaa kenttämerkit ja korvaa kentät niiden sisällöllä.
* Palauttaa uuden tekstin ja 'pos'in arvon sovitettuna uuteen tekstiin.
*/
function siivoa(text, pos) {
var ulkokentta = [-1, text.length+1];
var kentat = hae_alakentat(text, ulkokentta, 0);
var utext = poista_kentat(text, kentat);
var upos = laske_uusi_pos(kentat, pos);
return [utext, upos];
}
/**
* Sulkee annetun kentän.
* kentta[0],[1]: kentan ulkokohdat
* pos: kursorin kohta
**/
function sulje_kentta(text, kentta, pos) {
var sisakentta = Wikileike.hae_sisakentta(text, kentta);
sel.valitse(sisakentta[0], sisakentta[1]);
var valittu = sel.hae_valinta();
var ret = siivoa(valittu, pos-sisakentta[0]);
var siivottu = ret[0];
var upos = ret[1];
setTimeout(function() {
sel.korvaa(siivottu);
// Siirrytään loppuun.
sel.siirry(sisakentta[0] + upos);
}, 100);
}
/**
* Palauttaa sisimmän kentän jolla 'pos' on.
* FIX toimii vain jos 'taso' = 0
*/
function hae_sisin(taso, text, pos) {
var a = hae_edellinen(taso + 1, text, pos);
var l = hae_seuraava(-(taso + 1), text, pos);
if ( a == -1 ) a = -1;
if ( l == -1 ) l = text.length + 1; else l += 1;
return [a, l];
}
/**
* Hakee seuraavan kentan alku- ja loppukohdat. kentta[0] ja [1]:n täytyy
* osoittaa olemassa olevan kentan alku- ja loppukohtiin.
*/
function seuraava_kentta(text, kentta, ylakentta) {
var a = kentta[0], l = kentta[1],
ya = ylakentta[0], yl = ylakentta[1];
var spos = hae_seuraava(+1, text, l, yl);
if ( spos != -1 ) {
var viite = hae_sisin(0, text, spos+1);
return viite;
}
return null;
}
/**
* Palauttaa kentän sisältämät kentät taulukkona.
**/
function hae_alakentat(text, kentta, alkaen) {
assert ( alkaen >= kentta[0] && alkaen < kentta[1], "hae_alakentat" );
var sisakentta = Wikileike.hae_sisakentta(text, kentta);
var kentat = [];
var alakentta = [alkaen, alkaen];
while ( (alakentta = seuraava_kentta(text, alakentta, kentta))
!= null) {
var nimi = Wikileike.hae_kentan_otsikko(text, alakentta);
var s = Wikileike.hae_sisakentta(text, alakentta);
kentat.push([nimi, alakentta[0], alakentta[1], s[0], s[1]]);
}
return kentat;
}
/**
* Hakee ensimmäisen kentan.
*/
function eka_kentta(text, pos) {
var eka = seuraava_kentta(text, [pos, pos], [-1, text.length]);
if ( eka ) {
var ylakentta = hae_ylakentta(text, eka);
var kentat = taulukoi(text, ylakentta, pos);
console.log("Kentat(eka kentta): ", kentat);
if ( kentat.length > 0 ) {
var kentta = [ kentat[0][1], kentat[0][2], kentat[0][0] ];
return kentta;
}
}
return null;
}
/**
* Palauttaa kentan 'kentta' yläkentän eli kentän, jossa 'kentta'
* sijaitsee. Olettaa että 'kentta'[0],[1] on kentän alku- ja
* loppukohdat.
*/
function hae_ylakentta(text, kentta) {
return hae_sisin(0, text, kentta[1]);
}
/**
* Hakee edellisen kentan alku- ja loppukohdat. 'kentta'[0],[1] täytyy
* osoittaa olemassa olevan kentan alku- ja loppukohtiin.
**/
function edellinen_kentta(text, kentta) {
var spos = hae_edellinen(-1, text, kentta[0]);
if ( spos != -1 ) {
var kentta = hae_sisin(0, text, spos-1);
return kentta;
}
return null;
}
/**
* Palauttaa kentän 'nykykentta' indeksin 'taulukoi'-funktion tekemässä
* taulkossa 'kentat'.
*/
function hae_kentan_i(kentat, nykykentta) {
for ( var i = 0; i < kentat.length; i++ ) {
if ( kentat[i][1] == nykykentta[0]
&& kentat[i][2] == nykykentta[1] ) {
return i;
}
}
assert ( nyky_i != -1, "hae_kentan_i: nykykenttää ei löydy" );
return -1;
}
/**
* Tekee kentästä 'ylakentta' taulukon alkaen kohdasta 'alkaen'. Järjestää
* taulukon ensisijaisesti kentän numeron ja toissijaisesti sijainnin
* mukaan.
*/
function taulukoi(text, ylakentta, alkaen) {
assert ( alkaen >= ylakentta[0] && alkaen < ylakentta[1], "taulukoi");
var kentat = hae_alakentat(text, ylakentta, alkaen);
kentat.sort(function(a, b) {
if ( a[0] == b[0] ) {
return a[1] - b[1];
} else if ( a[0] == "" ) {
return +1;
} else if ( b[0] == "" ) {
return -1;
} else {
return a[0] - b[0];
}
});
return kentat;
}
/**
* Palauttaa kentän 'nykykenttä' n:nnen seuraavan tai edellisen
* sisarkentän tai null, jos kenttiä ei ole.
* Esim. suunta = -1 palauttaa edellisen kentän.
*/
function hae_sisarkentta(text, nykykentta, suunta) {
var ylakentta = hae_ylakentta(text, nykykentta);
var kentat = taulukoi(text, ylakentta, ylakentta[0]+1);
if ( suunta < 0 ) {
kentat.reverse();
}
console.log("Kentat(sisarkentta): ", kentat);
var nyky_i = hae_kentan_i(kentat, nykykentta);
var indeksi = nyky_i+Math.abs(suunta);
if ( indeksi < kentat.length && kentat[indeksi] ) {
var tmp = kentat[indeksi];
return [tmp[1], tmp[2], tmp[0]];
}
// Seuraavaa kenttää ei ole.
return null;
}
/**
* Asettaa kenttien, joiden nimi on 'nimi', sisällöksi 'arvon' kentän
* 'ylakentta' alla alkaen kohdasta 'alkaen'.
* Huom! Muuttaa tekstilaatikon sisältöä.
*/
function aseta_kentat_arvoon(text, ylakentta, alkaen, nimi, arvo) {
var kentat = hae_alakentat(text, ylakentta, alkaen);
var a = 0, text_o = [];
for ( e in kentat ) {
if ( kentat[e][0] == nimi ) {
text_o.push(text.substring(a, kentat[e][3]) + arvo);
a = kentat[e][4];
}
}
text_o.push(text.substring(a));
$textbox.val(text_o.join(""));
}
/**
* Palauttaa true tai false sen mukaan, onko kursorin ympäristön
* merkin poisto sallittu.
* suunta: kursoriin lisättävä etäisyys (+1/-1).
**/
function sallittu(suunta) {
var text = $textbox.val();
var ppos = sel.hae_kohdat();
// Sallitaan, jos tekstiä on valittu ja painetaan <backspace>a,
// vaikka edellinen olisi kielletty merkki, koska <backspace>n
// painaminen tässä tilanteessa poistaa vain valitun tekstin
// eikä edellistä merkkiä.
if ( suunta < 0 && ppos[0] != ppos[1] ) return true;
if ( ppos[0] >= 0 && ppos[0] < text.length ) {
var merkki = text[ppos[0] + suunta];
if ( merkki == "∷" || merkki == "⦃" || merkki == "⦄" ) {
return false;
}
}
return true;
}
function run($) {
$textbox = $("#wpTextbox1");
/**
* Näppäimistösyötteen käsittely.
**/
$textbox.on('keydown', $textbox, function(e) {
var keyCode = e.keyCode || e.which;
// Estetään kenttämerkkien tahaton poisto.
if ( keyCode == 8 ) { // <backspace>
if ( !sallittu(-1) ) {
return false;
}
} else if ( keyCode == 46 ) { // <del>
if ( !sallittu(0) ) {
return false;
}
} else if ( keyCode == 9 ) { // <tab>
e.preventDefault();
if ( e.shiftKey ) {
Wikileike.hyppaa_edelliseen();
} else {
Wikileike.hyppaa_seuraavaan();
}
} else if ( keyCode == 27 ) { // <esc>
e.preventDefault();
Wikileike.laajenna_leike();
}
//console.log("which: " + e.which);
});
/**
* Tekstin tallennuksen käsittely.
*
* Siivotaan varmuuden vuoksi ja tarkistetaan jäikö merkkejä
* ennen kuin teksti lähetetään.
**/
$("#editform").on('submit', function () {
var ret = siivoa($textbox.val());
var text = ret[0], upos = ret[1];
if ( text.search(/[⦃⦄∷]/) != -1 ) {
if ( confirm("Kaikkia kenttiä ei voitu sulkea. "
+ "Poistetaanko ⦃⦄∷-merkit väkisin ja tallennetaan sivu?") ) {
$textbox.val(text.replace(/⦃.*?∷/, "").replace(/[⦃⦄∷]/g, ""));
return true;
}
return false;
} else {
$textbox.val(text);
return true;
}
});
Wikileike.leikkeet = Leikkeet2.getSnippets();
}
window.Wikileike = Wikileike;
if ( (mw.config.get("wgAction") === "edit" || mw.config.get("wgAction") === "submit")
&& !(mw.config.get("wgPageName").endsWith(".js")
|| mw.config.get("wgPageName").startsWith("Moduuli:")) ) {
jQuery(document).ready(run);
}
})();
/**
* Sivujen muokkaustilassa näytettävä käyttöliittymäkoodi.
*
* Näyttää leikkeet luettelona ja linkit ohje- ja hallintasivulle työkalupalkissa.
**/
(function(){
/**
* Täyttää listan localStoragesta ladatun listan mukaiseksi.
*
* @param $leikelista: select-elementti (jQuery-kääreessä)
**/
function populateList($leikelista) {
var i, j,
keys,
$optSnp,
$optGrp,
tree = Leikkeet2.loadSnippetTree();
$leikelista.append('<option>- Lisää tekstileike -</option>');
for ( i in tree ) {
group = tree[i];
$optGrp = $('<optgroup/>');
$optGrp.attr("label", group.name);
for ( j in group.list ) {
snippet = group.list[j];
$optSnp = $('<option/>');
$optSnp.html(snippet.key);
$optSnp.attr("title", snippet.content);
$optGrp.append($optSnp);
}
$leikelista.append($optGrp);
}
};
/**
* Tekee hakasuluilla ympäröidyn linkin.
*
* @param text: linkin teksti
* @param title: linkin title-attribuutti
* @param url: linkin url
* @param fontsz: fontin koko css-muodossa tai null
**/
function makeLinkButton(text, title, url, fontsz) {
var $lnk,
$span;
$lnk = $('<a href="">' + text + '</a></div>');
$span = $('<span class="ohjenappi"/>');
$span.html([ "[", $lnk, "]" ]);
if ( fontsz ) {
$lnk.css("font-size", fontsz);
}
$lnk.attr("target", "_blank");
$lnk.attr("href", url);
$lnk.attr("title", title);
return $span;
}
/**
* Pääohjelma.
**/
function run() {
var $toolbar,
$ohje_span,
$manage_span,
$leikelista = $('<select/>'),
$toolbar = $('<span id="wl-alue"/>'),
$textbox = $("#wpTextbox1");
$ohje_span = makeLinkButton('?', 'Avaa "Tekstileikkeet"-pienoisohjelman ohje.', Leikkeet2.helpUrl, null);
$manage_span = makeLinkButton('Hallitse leikkeitä',
'Siirry leikkeiden hallintasivulle.', Leikkeet2.getManagePageUrl(), "90%");
$toolbar.append([ $leikelista, " ", $manage_span, " ", $ohje_span ]);
/* Jos joku toinen gadgetti on jo lisännyt työkalupalkin, lisätään siihen
muuten luodaan oma. */
(function () {
var $tb = $("#tyokalupakki");
if ( $tb.length > 0 ) {
$tb.append([ '<span class="tyokaluerotin" style="color: gray;">'
+ ' | </span>', $toolbar ]);
} else {
$tb = $('<div id="tyokalupakki" />');
$textbox.before($tb);
$("#tyokalupakki").append($toolbar);
}
}());
populateList($leikelista);
/**
* Leikelistasta valinta.
*
* Kutsutaan, kun leikelistasta valitaan uusi leike.
**/
$leikelista.change(function () {
var snippetname = $(this).val();
// Valitaan "- Lisää leike -" -teksti takaisin.
$(this).children(':nth(0)').prop('selected', true);
$textbox.textSelection('replaceSelection', snippetname);
$textbox.focus();
Wikileike.laajenna_leike();
});
}
if ( mw.config.get("wgAction") == "edit" || mw.config.get("wgAction") == "submit"
&& !(mw.config.get("wgPageName").endsWith(".js")
|| mw.config.get("wgPageName").startsWith("Moduuli:"))
&& (mw.config.get("wgPageName") != "Järjestelmäviesti:Gadget-Tekstileikkeet.js") ) {
jQuery(document).ready(run);
}
})();
/**
* Leikkeiden hallintasivun koodi.
**/
if ( mw.config.get("wgTitle") === Leikkeet2.getManagePageTitle() ) {
(function () {
var __g = {
/**
* Asetetaan trueksi, kun tehdään muutoksia, ja falseksi
* tallennettaessa.
**/
stateChanged : false,
/**
* Dict varatuista leikkeennimistä. Esim. { "leike" : { }, ... }.
**/
snippets : {},
/**
* Dict varatuista ryhmännimistä. Esim. { "ryhmä" : true, ... }.
**/
g_groups : {}
};
/**
* Kysyy varmistusta ja poistaa leikkeen.
**/
function deleteLnk_askDeleteSnippet() {
var $lnk = $(this);
var $container = $lnk.parent();
var $span = $container.find('.wl-snippet-key');
var $pre = $container.find('.wl-snippet-val');
var snippetName = $span.text();
var snippetContent = $pre.text();
if ( window.confirm('Haluatko varmasti poistaa leikkeen "' + snippetName +
'"?\nSisältö:\n ' + snippetContent.replace(/\n/g, "\n ")) ) {
$container.remove();
updateWorkingData();
}
return false;
}
/**
* Kysyy varmistusta ja poistaa ryhmän.
**/
function deleteLnk_askDeleteGroup() {
var $lnk = $(this);
var $container = $lnk.parent();
var $groupLbl = $container.find('.wl-group-name');
var groupName = $groupLbl.text();
var groupContent = Array.map($container.find('.wl-snippet-key'), function (item) { return item.innerHTML }).join(",\n * ");
if ( window.confirm('Haluatko varmasti poistaa ryhmän "' + groupName +
'"?\nSisältö:\n ' + groupContent) ) {
$container.remove();
updateWorkingData();
}
return false;
}
/**
* Tallentaa leikkeen ja sulkee editoinnin.
**/
function saveBtn_saveEditSnippet() {
var $closeBtn = $(this);
var $editor = $closeBtn.parents('.wl-editor');
var $container = $editor.parent();
var $groupContainer = $container.parent().parent();
var $span = $container.find('.wl-snippet-key');
var $pre = $container.find('.wl-snippet-val');
var $inp = $editor.find('input[type="text"]');
var $ta = $editor.find('textarea');
var $groupLabel = $groupContainer.find('.wl-group-name');
var oldName = $span.text();
var newName = $inp.val();
var content = $ta.val();
var group = $groupLabel.text();
if ( newName === "" ) {
alert("Leikkeellä pitää olla nim!i");
return false;
}
if ( newName != oldName && (newName in __g.snippets) ) {
alert('Leike "' + newName + '" on jo olemassa!');
return false;
}
if ( content === "" ) {
alert('Leikkeellä pitää olla sisältö!');
return false;
}
$span.text(newName);
$pre.text(content);
// Palautetaan siirrettävyys, jos se oli pois päältä.
// Koskee vain tuontia.
if ( $span.parent().hasClass('snippet-conflicting') ) {
$span.parent().addClass('snippet-new');
$span.parent().removeClass('snippet-conflicting')
}
$editor.remove();
updateWorkingData();
// Laukaistaan eventti listassa.
$container.change();
return false;
}
/**
* Tallentaa ryhmän ja sulkee editoinnin. Tallennus-painikkeesta.
**/
function saveBtn_saveEditGroup() {
var $closeBtn = $(this);
var $editor = $closeBtn.parents('.wl-editor');
var $container = $editor.parent();
var $groupLbl = $container.find('.wl-group-name');
var $inp = $editor.find('input[type="text"]');
var oldName = $groupLbl.text();
var newName = $inp.val();
if ( newName == "" ) {
alert("Ryhmällä pitää olla nimi!");
return;
}
if ( newName in __g.groups ) {
alert('Ryhmä nimeltä "' + newName + '" on jo olemassa.') ;
$inp.focus();
return false;
}
$groupLbl.text(newName);
$editor.remove();
updateWorkingData();
// Laukaistaan eventti listassa.
$container.change();
return false;
}
/**
* Sulkee leikkeen editoinnin tallentamatta. Peruutus-painikkeesta.
**/
function cancelBtn_cancelEditSnippet() {
var $closeBtn = $(this);
var $editor = $closeBtn.parents('.wl-editor');
var $container = $editor.parent();
var $editLnk = $container.find('a[title="Muokkaa leikettä"]');
var $span = $container.find('.wl-snippet-key');
// Jos span oli tyhjä, oli kyseessä uuden leikkeen luonti. Poistetaan koko höskä.
if ( $span.text() == "" ) {
$container.remove();
} else {
$editor.remove();
}
return false;
}
/**
* Sulkee ryhmän editoinnin tallentamatta. TODO
**/
function cancelBtn_cancelEditGroup() {
var $closeBtn = $(this);
var $editor = $closeBtn.parents('.wl-editor');
var $container = $editor.parent();
var $groupLbl = $container.find('.wl-group-name');
var $editLnk = $container.find('a[title="Muokkaa ryhmää"]');
var name = $groupLbl.text();
// Jos groupLbl oli tyhjä, oli kyseessä uuden ryhmän luonti. Poistetaan koko höskä.
if ( name == "" ) {
$container.remove();
} else {
$editor.remove();
}
return false;
}
/**
* Avaa editorielementin annetulle .snippet- tai .group-elementille.
**/
function openEditor($container, text1, text2, saveBtn_saveEdit, cancelBtn_cancelEdit) {
var $editor = $('<div class="wl-editor" style="overflow: auto; width: 100%;"></div>');
var $buttonCont = $('<div style="float: right;"></div>');
$editor.append('<input type="text" value="' + text1 + '" />');
if ( text2 !== null ) {
$editor.append('<textarea>' + text2 + '</textarea>');
}
$buttonCont.append('<input type="button" value="Tallenna" />');
$buttonCont.append('<input type="button" value="Peruuta" />');
$editor.append($buttonCont);
$buttonCont.find('input[value="Tallenna"]').on('click', saveBtn_saveEdit);
$buttonCont.find('input[value="Peruuta"]').on('click', cancelBtn_cancelEdit);
// Lisätään poistonapin jälkeiseksi elementiksi.
$container.children('a[title="Poista leike"], a[title="Poista ryhmä"]').after($editor);
$editor.find('input[type="text"]').focus();
}
/**
* Avaa leikkeen editoitavaksi.
**/
function editLnk_openEditSnippet() {
var $editLnk = $(this);
var $container = $editLnk.parent();
var $span = $container.find('.wl-snippet-key');
var $pre = $container.find('.wl-snippet-val');
var key = $span.text();
var val = $pre.text();
var $editor = $container.children('.wl-editor');
if ( $editor.length > 0 ) {
$editor.remove();
} else {
openEditor($container, key, val, saveBtn_saveEditSnippet, cancelBtn_cancelEditSnippet);
}
return false;
}
/**
* Avaa ryhmän editoitavaksi.
**/
function editLnk_openEditGroup() {
var $editLnk = $(this);
var $container = $editLnk.parent();
var $groupLbl = $container.find('.wl-group-name');
var groupName = $groupLbl.text();
var $editor = $container.children('.wl-editor');
if ( $editor.length > 0 ) {
$editor.remove();
} else {
openEditor($container, groupName, null, saveBtn_saveEditGroup, cancelBtn_cancelEditGroup);
}
return false;
}
/**
* Tekee leikelistan elemetin.
**/
function makeSnippetItem(key, val) {
var $item = $('<li class="wl-snippet"></li>');
$item.append([ '<span class="wl-snippet-key">' + key + '</span>',
' ',
'<a href="" title="Muokkaa leikettä">[m]</a>',
'<a href="" title="Poista leike">[p]</a>',
'<pre class="wl-snippet-val"">' + val + '</pre>' ]);
$item.find('a[title="Muokkaa leikettä"]').on('click', editLnk_openEditSnippet);
$item.find('a[title="Poista leike"]').on('click', deleteLnk_askDeleteSnippet);
return $item;
}
/**
* Tekee leikelistan, jossa on lisäysnappi valmiina.
**/
function makeSnippetList() {
var $list = $('<ul class="wl-snippet-list"></ul>');
var $adder = $('<li class="wl-snippet-adder"></li>');
$adder.append('<a href="" title="Uusi leike">[uusi leike]</a>');
$adder.children('a[title="Uusi leike"]').on('click', newLnk_openAddSnippet);
$list.append($adder);
if ( $list.sortable ) {
$list.sortable({ connectWith: ".wl-snippet-list",
items: ".wl-snippet, .snippet-new",
change: list_sortChange });
}
return $list;
}
/**
* Tekee ryhmälistan elementin, jossa on sisälle tyhjä leikelista.
**/
function makeGroupItem(name) {
var $snippetList = makeSnippetList();
var $groupItem = $('<li class="wl-group mw-collapsible"></li>').append([
'<b class="wl-group-name">' + name + '<b/>',
' ',
'<a href="" title="Muokkaa ryhmää">[m]</a>',
'<a href="" title="Poista ryhmä">[p]</a>',
' ',
$snippetList ]);
$groupItem.find('a[title="Muokkaa ryhmää"]').on('click', editLnk_openEditGroup);
$groupItem.find('a[title="Poista ryhmä"]').on('click', deleteLnk_askDeleteGroup);
return $groupItem;
}
/**
* Avaa leikkeen editoitavaksi.
**/
function newLnk_openAddSnippet() {
var $newLnk = $(this);
var $adder = $newLnk.parent();
var $item = makeSnippetItem("", "");
$adder.before($item);
$item.children('a[title="Muokkaa leikettä"]').click();
return false;
}
/**
* Avaa ryhmän editoitavaksi.
**/
function newLnk_openAddGroup() {
var $newLnk = $(this);
var $groupAdder = $newLnk.parent();
var $groupItem = makeGroupItem("");
$groupAdder.before($groupItem);
$groupItem.children('a[title="Muokkaa ryhmää"]').click();
return false;
}
/**
* Tallentaa puunäkymän leikkeet localStorageen.
**/
function saveSnippetTree() {
var groupList = getGroupList($('#wl-group-list'));
var out = Leikkeet2.decodeSnippets(groupList);
Leikkeet2.saveSnippetTree(out);
__g.stateChanged = false;
//window.location.reload();
}
/**
* Tallentaa puunäkymän leikkeet localStorageen.
**/
function loadSnippetTree() {
var groupList = Leikkeet2.loadSnippetTree();
__g.stateChanged = false;
if ( groupList ) {
return Leikkeet2.encodeSnippets(groupList);
}
return null;
}
/**
* Lukee groupListin tiedot sivun elementeistä.
*
* @return: esim. [ { "name" : "ryhmä a",
* "index" : 0,
* "list" : [ { "key" : "leike a1",
* "index" : 0,
* "content": "AAAAA" },
* { "key" : "leike a2",
* "index" : 1,
* "content" : "AAA" } ] },
* { "name" : "ryhmä b", ... ] } ]
**/
function getGroupList($listRoot) {
var rootList = [];
$listRoot.children(".wl-group").each(function () {
var $this = $(this);
var group = $this.children('.wl-group-name').text();
rootList.push({
"name" : group,
"index": rootList.length,
"list" : [] });
$this.children('.wl-snippet-list').children('.wl-snippet').each(function () {
var $this = $(this);
rootList[rootList.length - 1].list.push({
"key" : $this.children('.wl-snippet-key').text(),
"index" : rootList[rootList.length - 1].list.length,
"content" : $this.children('.wl-snippet-val').text() });
});
});
return rootList;
}
/**
* Päivittää varattujen nimien dictit annetun ryhmälistan mukaiseksi.
*
* @param groupList: ryhmän mukaan järjestetty lista leikelistoista.
**/
function loadWorkingData(groupList) {
var i, j;
var group;
var snippet;
__g.snippets = {};
__g.groups = {};
for ( i in groupList ) {
group = groupList[i];
for ( j in group.list ) {
snippet = group.list[j];
__g.snippets[snippet.key] = group.list[j];
}
__g.groups[group.name] = groupList[i];
}
__g.stateChanged = true;
}
/**
* Päivittää varattujen nimien datan nykyisen puun mukaiseksi.
**/
function updateWorkingData() {
var byGroup = getGroupList($('#wl-group-list'));
loadWorkingData(byGroup);
}
/**
* "Kääntää" taulukon siten, että tiedot on järjestetty ryhmän mukaan.
* TODO: Onko turha?
**/
function snippetDictToGroupList(snippets) {
var turned = {};
var group;
var content;
var key;
var byGroup = [];
for ( key in snippets ) {
group = snippets[key].group;
content = snippets[key].content;
index = snippets[key].index;
if ( !(group in turned) ) {
turned[group] = [];
}
turned[group].push({ "key" : key,
"content" : content,
"index" : index });
}
for ( key in turned ) {
// Lajitellaan nousevaan järjestykseen avaimen mukaan.
byGroup.push({
"name" : key,
"list" : turned[key].sort(function (a, b) { return a.index - b.index; }),
"index": byGroup.length
});
}
return byGroup.sort(function (a, b) { return a.index - b.index; });
}
/**
* Kutsutaan kun ryhmä- tai leikelistaa muutetaan.
**/
function list_sortChange(e) {
var $list = $(this)
var $adder = $list.children('.wl-snippet-adder, .wl-group-adder');
// Varmistetaan, että lisäysnappi jää alimmaksi.
$list.append($adder.detach());
__g.stateChanged = true;
}
/**
* Kutsutaan kun nimi (TODO) tai jokin jäsenistä muuttuu.
**/
function group_onChange() {
var $this = $(this);
if ( ! __g.groups[$this.children('.wl-group-name').text()] ) {
return;
}
// Tarkistetaan onko jäseniä joita ei voi liikuttaa.
if ( $this.children('.wl-snippet_conflicting').length == 0 ) {
$this.removeClass('group-conflicting').addClass('group');
} else {
$this.addClass('group-conflicting').removeClass('group');
}
}
/**
* Antaa koko puun JSON-muodossa kopiotavaksi.
**/
function openExportSnippetTree() {
var $imex = $('#wl-import-export');
var $ta = $('#wl-import-export-data');
var groupList = getGroupList($('#wl-group-list'));
var $groupList = $('#wl-group-list');
$ta.val(JSON.stringify(Leikkeet2.decodeSnippets(groupList), null, 2));
$(".wl-snippet-ui-edit").css('display', 'none');
$(".wl-snippet-ui-export").css('display', '');
$ta.focus().select();
}
/**
* Antaa koko puun JSON-muodossa kopiotavaksi.
**/
function openImportSnippetTree() {
var $imex = $('#wl-import-export');
var $ta = $('#wl-import-export-data');
var $groupList = $('#wl-group-list');
$(".wl-snippet-ui-edit").css('display', 'none');
$(".wl-snippet-ui-import").css('display', '');
$ta.val("");
$ta.focus();
}
function closeImportExport() {
$(".wl-snippet-ui-import").css('display', 'none');
$(".wl-snippet-ui-export").css('display', 'none');
$(".wl-snippet-ui-edit").css('display', '');
}
/**
* Rakentaa editoitavan puun annetusta datasta annettuun elementtiin.
**/
function makeSnippetTree($groupList, groupList) {
var $snippetList;
var $groupItem;
var $snippetItem;
var $snippetAdder;
var i, j;
var group;
$groupList.empty();
for ( i in groupList ) {
__g.groups[groupList[i].name] = true;
group = groupList[i].list;
$groupItem = makeGroupItem(groupList[i].name);
$snippetList = $groupItem.children(':last-child');
$snippetAdder = $snippetList.children(":last-child");
for ( j in group ) {
$snippetItem = makeSnippetItem(group[j].key, group[j].content);
if ( group[j].flag === "new" ) {
$snippetItem.addClass('snippet-new');
} else if ( group[j].flag === "deleted" ) {
$snippetItem.addClass('snippet-deleted');
} else if ( group[j].flag === "conflict" ) {
$snippetItem.addClass('snippet-conflicting');
// Poistetaan siirrettävyys kunnes nimi on muutettu. TODO
$snippetItem.removeClass('snippet');
$groupItem.removeClass('group');
}
$snippetAdder.before($snippetItem);
}
$groupItem.on('change', group_onChange);
$groupList.append($groupItem);
}
$groupList.append($('<li class="wl-group-adder"></li>')
.append($('<a href="">[uusi ryhmä]</a>')
.on('click', newLnk_openAddGroup)));
if ( $groupList.sortable ) {
$groupList.sortable({
connectWith: ".wl-group-list",
change: list_sortChange,
items : '.wl-group',
placeholder: "sortable-placeholder" });
}
}
function importSnippetTree() {
var $ta = $('#wl-import-export-data');
var importedGroupList = JSON.parse($ta.val());
__g.stateChanged = true;
makeSnippetTree($('#wl-group-list'), importedGroupList);
closeImportExport();
}
/**
* Koodi, jota kutsutaan kun sivu on ladattu.
**/
function main() {
var $div = $('<div id="wl-main"></div>');
var $divEdit = $('<div class="wl-snippet-ui-edit"></div>');
var $groupList = $('<ul class="wl-group-list" id="wl-group-list"></ul>');
// Importissa ja exportissa käytettävä tekstilaatikko.
var $ta = $('<textarea id="wl-import-export-data"></textarea>');
var $divImEx = $('<div id="wl-import-export" class="wl-snippet-ui-import snippet-ui-export"></div>');
var groupList = loadSnippetTree();
loadWorkingData(groupList);
__g.stateChanged = false;
makeSnippetTree($groupList, groupList);
$divImEx.append([
$('<h2 class="wl-snippet-ui-import">Tuo</h2>'),
$('<h2 class="wl-snippet-ui-export">Vie</h2>'),
$('<p class="wl-snippet-ui-import">Kopioi tallenetut leikkeet alla olevaan laatikkoon.<br/><br/>Huom. OK:n painaminen korvaa vanhat leikkeet uusilla!</p>'),
$ta,
$('<button class="wl-snippet-ui-export">Sulje</button>').on('click', closeImportExport),
$('<button class="wl-snippet-ui-import">Peruuta</button>').on('click', closeImportExport),
$('<button class="wl-snippet-ui-import">OK</button>').on('click', importSnippetTree) ]);
$divEdit.append([
'<h2>Leikkeet</h2>',
$('<button title="Tallenna muutokset">Tallenna</button>').on('click', saveSnippetTree),
$groupList,
"<br/><hr/>",
$('<button title="Tuo tallennetut leikkeet">Tuo</button>').on('click', openImportSnippetTree),
$('<button title="Ota kopio leikkeistä">Vie</button>').on('click', openExportSnippetTree) ]);
$div.append([ $divEdit,
$divImEx ]);
$("#mw-content-text").replaceWith($div);
$(".wl-snippet-ui-import").css('display', 'none');
$(".wl-snippet-ui-export").css('display', 'none');
// Kysytään käyttäjältä varmistusta ennen sivulta siirtymistä, jos tietoja
// on tallentamatta.
window.addEventListener('beforeunload', function (e) {
if ( __g.stateChanged ) {
e.preventDefault();
e.returnValue = '';
}
});
}
jQuery(document).ready(main);
}());
}