MediaWiki:Gadget-MoreLinks.js

Aus Wiktionary, dem freien Wörterbuch
//<nowiki>
"use strict";

// begin namespace: foMoreLinks
(function( _public, $, undefined ) {

var pBeddl = {};  // <DL> bei Bedeutungen
var pBspdl = {};  // <DL> bei Beispielen

var bspTab = [];  // Tabelle der Beispiele mit {element,sprache,text}
var statb = 0;
var stata = 0;
var statu = 0;

var wordb = [];
var worda = [];
var wordu = [];
var wortbild = {};    // Wortbildung
var wordCat = {};     // Alle Wörter mit Kategorien
var wordTab25 = [];   // erste 25 Wörter, die zur Sprachermittlung dienen
var sprachname = "Deutsch";   // Voreinstellung
var inputWords = {};

var fuge = ["", "e", "n", "s", "en", "er", "es"];

var sp3 = String.fromCharCode(32,160,32);

var limitCnt = 0;
var limitTxt = '';

// Alle <DL>-Elemente als Sibling zu den Abschnittsüberschriften "Bedeutungen" und "Beispiele"
// ermitteln. <DL>-Elemente werden durch die Doppelpunkte am Zeilenanfang erzeugt.
// Die jeweiligen Abschnitte werden entweder durch <P> oder <H4> abgeschlossen.

_public.init = function ()
{
  var pBed = $("p[title='Sinn und Bezeichnetes (Semantik)']");
  var pBsp = $("p[title='Verwendungsbeispielsätze']");

  pBeddl = $(pBed).nextUntil("P,H4","DL");
  if (pBeddl.length > 0) {
    $(pBed).each(function() {
     this.insertAdjacentHTML("beforeend",
      ' <a class="foMoreLinks noprint" href="#" onclick="foMoreLinks.fLinks()'+';return false;">'+'prüfen</a>');
    });
  }
  pBspdl = $(pBsp).nextUntil("P,H4","DL");
  if (pBspdl.length > 0) {
    $(pBsp).each(function() {
     this.insertAdjacentHTML("beforeend",
      ' <a class="foMoreLinks noprint" href="#" onclick="foMoreLinks.fLinks()'+';return false;">'+'prüfen</a>');
    });
  }

}


// Aus der HTML-Seite zu Bedeutungen und Beispielen die enthaltenen Wörter auslesen
// jQ.find sucht rekursiv den Elementbaum durch.

_public.fLinks = function () {
  var txt = '';
  $(".foMoreLinks").hide();

  // Beispiele mit Sprachüberschriften zur Sprachzuordnung
  var head2Bsp = document.querySelectorAll("h2 span.mw-headline, p[title='Verwendungsbeispielsätze']");

// Die Sprache des Abschnitts aus den SPAN-Elementen der H2-Überschrift ermitteln.
// Dann jeweils nur die Beispiele nach den einfachen ':' auslesen.
// Dort befinden sich die Beispiele in der jeweiligen Sprache.
// Die deutschen Übersetzungen stehen nach doppeltem '::'

  for (var i = 0; i < head2Bsp.length; i++) {
    if (head2Bsp[i].nodeName == "SPAN") {  // Header <H2>; Sprache aus dem <span> zwischen () lesen
      var spr = head2Bsp[i].innerText;
      var idx1 = spr.indexOf('(');
      if (idx1 >= 0) {
        spr = spr.slice(idx1 + 1,spr.indexOf(')'));
      }
    }
    if (head2Bsp[i].nodeName == "P") {  // Paragraph <P>; für Responsezugriff in bspTab speichern
      var txt1 = '';
      var collect = $(head2Bsp[i]).nextUntil("P,H4","DL");
      collect.children("DD").each(function(index, element) {
        txt1 += getWords(element);
      });
      bspTab.push({element:collect, spr:spr, text:txt1});
    }
  }

  $(pBeddl).add(pBspdl).find("DD").each(function(index, element) {
    txt += getWords(element);
  });

  if (txt.length > 0) {
    var url = buildApi('',"action=parse&prop=links&format=json");
    $.post(url, {text: txt}, handleResponseLinks);
  }
}


_public.sucheLinks = function () {

  function handleResponseSucheLinks(data) {
    if (data.parse !== undefined && data.parse.links !== undefined) {
      var dpl = data.parse.links;
      var i = dpl.length-1;

      for (; i >= 0; i--) {
        var t = dpl[i]['*'];
        if (dpl[i].hasOwnProperty("exists") && t.length > 0) {
          wortbild[t] = true;
        }
      }
      wortbildung(htm);
    }
  }

  var htm = this;
  var w = htm.title.replace(/-/g,'');
  var txt = '';
  for (var i = 1; i < w.length - 1; i++) {
    var s1 = w.slice(0,i);
    var s2 = w.slice(i);
    var s1u = toUpper1(s1);
    var s2u = toUpper1(s2);
    txt += wikiLink(s1u) + wikiLink(s2u) + wikiLink(s1u+'-') + wikiLink('-'+s2);
  }

  if (txt.length > 0) {
    var url = buildApi('',"action=parse&prop=links&format=json");
    $.post(url, {text: txt}, handleResponseSucheLinks);
  } else {
    wortbildung(htm);
  }
  return false;  // prevent page reload
}


function wortbildung(htm) {
  var w = htm.title.replace(/-/g,'');
  var result = [];
  var maxEndglied = '';

  for (var i = 1; i < w.length - 1; i++) {
    var s1 = w.slice(0,i);
    var a1 = [];
    a1.push(toUpper1(s1));
    a1.push(toLower1(s1));
    a1.push(toUpper1(s1) + '-');
    a1.push(toLower1(s1) + '-');
    for (var i1 = 0; i1 < a1.length; i1++) {
      if (wortbild.hasOwnProperty(a1[i1])) {
        for (var j = 0; j < fuge.length; j++) {
          if (!w.startsWith(s1 + fuge[j])) {
            continue;
          }

          var s2 = w.slice(i + fuge[j].length);
          var a2 = [];
          a2.push(toUpper1(s2));
          a2.push(toLower1(s2));
          a2.push('-' + toUpper1(s2));
          a2.push('-' + toLower1(s2));
          for (var j1 = 0; j1 < a2.length; j1++) {
            if (wortbild.hasOwnProperty(a2[j1])) {
              result.push(a1[i1] +'+'+ fuge[j] +'+'+ a2[j1]);
            }
          }
        }
      }
    }
  }

  var txt = " unbekannt";
  if (w.match(/^[0-9]+$/)) {
    txt = " eine Zahl";
    if (w.length == 4 && w < "2199") {
      txt += ", vielleicht eine Jahreszahl";
    }
  }
  if (result.length > 0) {
    txt = " wohl gebildet aus";
    for (i = 0; i < result.length; i++) {
      txt += (i > 0) ? " oder " : " ";
      txt += result[i];
    }
  }
  txt = txt.replace(/\+\+/g,'+');

  var anker = htm.parentElement.querySelector("a[title='" + htm.title + "']");
  htm.parentElement.insertBefore(document.createTextNode(txt), anker.nextElementSibling.nextElementSibling);

}


_public.initCheck = function () {
  var form,node;
  document.getElementById("MLinput").textContent = "";

  form = newNode(
   'form',
   {'class':'noprint','id':'MLexternform'},
     newNode('label','Url: '),
     newNode('input',{'type':'text','id':'externurl','size':'30'}),
     newNode('label',' Api: '),
     newNode('input',{'type':'text','id':'externapi'}),
     newNode('label',' Seite: '),
     newNode('input',{'type':'text','id':'externpage','size':'42'}), ' ',
   newNode('input',{'type':'button','id':'doload','value':'Laden',
    'onclick':'foMoreLinks.doLoad()'})
  );
  form.onsubmit = foMoreLinks.doLoad;
  node = document.getElementById("MLextern");
  node.appendChild(form);

  $("#MLextern").before('<a href="#" onclick="foMoreLinks.doMehr()'+';return false;">'+'mehr</a>');

  document.getElementById("MLinput").textContent = "";

  form = newNode(
   'form',
   {'class':'noprint','id':'thisform'},
   //  newNode('label','Eingabe: ',
   //  newNode('input',{'name':'pagefrom','id':'morfegap','type':'text','size':'50'})),
     newNode('label','Dein Text: '),
     newNode('textarea',{'form':'thisform','id':'userinput','rows':'8'}),
   newNode('input',{'type':'button','id':'docheck','value':'Existenz prüfen',
    'onclick':'foMoreLinks.doCheck()'}), ' ',
   newNode('input',{'type':'button','id':'dosprache','value':'Sprache ermitteln',
    'onclick':'foMoreLinks.doSprache()'}), ' ',
   newNode('span',{'id':'sprache'}), ' ',
   newNode('input',{'type':'button','id':'dochecksprache','value':'Sprachzugehörigkeit prüfen',
    'onclick':'foMoreLinks.doCheckSprache()'}), ' ',
   newNode('input',{'type':'button','id':'doclear','value':'Leeren',
    'onclick':'foMoreLinks.doClear()'})
  );
 
  form.onsubmit = foMoreLinks.doCheck;
  node = document.getElementById("MLinput");
  node.parentNode.insertBefore(form,node);

  $("#MLaw").after(sp3,'<a href="#" onclick="foMoreLinks.doDetails()'+';return false;">'+'Unbekannte Wörter:</a>');
}


_public.doMehr = function () { // Formular zum Laden externer Seiten
  $("#MLextern").show();
}


_public.doCheck108 = function () {  // Flexionsseite (Verben)
  var input = document.getElementById("mw-content-text");
  var txt = getWordsFromText(input.textContent,0);
  if (txt.length > 0) {
    var url = buildApi('',"action=parse&prop=links&format=json");
    $.post(url, {text: txt}, handleResponseLinks);
  }
}


_public.doSprache = function () {
  var input = document.getElementById("userinput").value;
  input = input.replace(/\u00ad/g, "");  // Softhyphen
  var txt = '';
  wordTab25 = getWordTabFromText(input,25);

  for (var i = 0; i < wordTab25.length; i++) {
    txt += wikiList(wordTab25[i]);
  }
  if (txt.length > 0) {
    var url = buildApi('',"action=query&prop=categories&clshow=!hidden&cllimit=5000&format=json");
    $.post(url, {titles: txt}, handleResponseCats);
  }
}


_public.doLoad = function () {
  var url = document.getElementById("externurl").value;
  var api = document.getElementById("externapi").value;
  var page = document.getElementById("externpage").value.trim();
  if (page.length > 0) {
    if (api.length == 0) {
      api = mw.config.get("wgScriptPath") + "/api.php";
      document.getElementById("externapi").value = api;
    }
    if (url.length == 0) {
      url = mw.config.get("wgServer");
      document.getElementById("externurl").value = url;
    }
    var cross = url != mw.config.get("wgServer");
    var data = {
        action: 'parse',
        prop: 'text',
        page: page,
        disablelimitreport: '1',
        disableeditsection: '1',
        disabletoc: '1',
        format: 'json'
      };
    if (cross) {
      data.origin = window.location.origin;
    }
    var jqxhr = $.ajax( {
      url: url + api,
      data: data,
      error: function(xhr, status, error) { alert(xhr.responseText); },
      xhrFields: {
        withCredentials: cross
      },
      dataType: 'json'
    } ).done( handleResponseUrl );

  }
}


_public.doCheck = function () {
  var input = document.getElementById("userinput").value;
  input = input.replace(/\u00ad/g, "");  // Softhyphen
  wordb = [];
  worda = [];
  wordu = [];
  document.getElementById("MLDetails").textContent = "";

  if (input.slice(0,4) == "http") {
    var idx = input.indexOf(" ");
    if (idx > 4) {
      var url = input.slice(0,idx);
      var idx2 = input.indexOf("$");
      var page = input.slice(idx + 1,idx2); 
      $.ajax( {
        url: url,
        data: {
          action: 'parse',
          prop: 'text',
          page: page,
          disablelimitreport: '1',
          disableeditsection: '1',
          disabletoc: '1',
          format: 'json',
          origin: window.location.origin
        },
        error: function(xhr, status, error) {  alert(xhr.responseText);},
        xhrFields: {
          withCredentials: true
        },
        dataType: 'json'
      } ).done(handleResponseUrl)
         ;return;
    }
  }

  var txt = getWordsFromText(input,0);
  if (txt.length > 0) {
    var url = buildApi('',"action=parse&prop=links&format=json");
    $.post(url, {text: txt}, handleResponseLinks);
  }
  document.getElementById("MLoutput").textContent = input;
}


function handleResponseUrl(data) {
  var i0 = document.getElementById("MLinput0");
  if (data.parse !== undefined && data.parse.text !== undefined) {
    var txt = data.parse.text['*'];
    do {
      var idx1 = txt.indexOf('<style data');
      var idx2 = txt.indexOf('</style>');
      if (idx1 > 0 && idx2 > 0) {  // remove template styles
        txt = txt.slice(0,idx1) + txt.slice(idx2 + 8);
      }
    } while (idx1 > 0 && idx2 > 0)
    // line break, sonst werden durch <br> getrennte Wörter aneinander geklebt
    txt = txt.replace(/<br>/gi, "\n");
    txt = txt.replace(/<br \/>/gi, "\n");
    txt = txt.replace(/\u00ad/g, "");  // Softhyphen
    i0.innerHTML = txt;
  }
  if (data.error !== undefined && data.error.info !== undefined) {
    i0.innerHTML = data.error.info;
  }
  document.getElementById("userinput").value = i0.innerText.trim();
  i0.innerHTML = '';
}


// Sprachzugehörigkeit der Wörter aus den Beispielen (bspTab) prüfen
_public.doCheck1 = function () {

  for (var i = 0; i < bspTab.length; i++) {
    var atxt = bspTab[i].text.split("]][[");  // !!![[ und ]]
    if (atxt.length > 0) {
      atxt[0] = atxt[0].replace("[[","");
      atxt[atxt.length - 1] = atxt[atxt.length - 1].replace("]]","");
    }
    for (var j = 0; j < atxt.length; j++) {
      limit50(atxt[j],i,bspTab[i].spr,handleResponseCats1);
    }
    if (limitTxt.length > 0) { //flush
     limit50(null,i,bspTab[i].spr,handleResponseCats1);
    }
  }

}


// Sprachzugehörigkeit der Wörter aus dem Inputtext prüfen (Was noch fehlt)
_public.doCheckSprache = function (words) {

  for (var w in inputWords) {
    limit50(w,0,sprachname,handleResponseCats2);
  }
  if (limitTxt.length > 0) { //flush
    limit50(null,0,sprachname,handleResponseCats2);
  }

}


_public.doClear = function () {
  document.getElementById("userinput").value = "";
  $("#MLStatistik").hide();
  $("#MLDetails").hide();
  document.getElementById("sprache").innerHTML = "";
  document.getElementById("MLoutput").textContent = "";
  document.getElementById("MLSprache").textContent = "";
  wordTab25 = [];
  inputWords = {};
}


_public.doDetails = function () {

  var element = document.getElementById("MLDetails");
  if (element) {
    var nn = element.cloneNode(false);
    wordu.sort();
    var cnt = 0;
    var lastword = "";
    for (var i = 0; i < wordu.length; i++) {
      if (i < wordu.length - 1 && wordu[i] == wordu[i+1]) {
        cnt++;
      } else {
        if (i == wordu.length - 1) {
          ;
        }
   
        var nl = document.createElement("a");
        nl.href = "#";
        nl.innerHTML = "[?]";
        nl.title = wordu[i];
        nl.onclick = foMoreLinks.sucheLinks;
        nn.appendChild(nl);
        nn.appendChild(document.createTextNode(' '));

        newLinkRed(nn,wordu[i]);
        if (cnt > 0) {
          nn.appendChild(document.createTextNode(' (' + (cnt+1) + ')'));
        }
        nn.appendChild(document.createElement("BR"));

        cnt = 0;
      }
    }
    element.parentNode.replaceChild(nn, element);
  }
}


// Anzeige der Kategorien zur Sprachermittlung
_public.doDetailsSprache = function () {

  var element = document.getElementById("MLSprache");
  if (element) {
    var nn = element.cloneNode(false);

    for (var i = 0; i < wordTab25.length; i++) {
      var bold = document.createElement("SPAN");
      bold.style.fontWeight = "bold";
      bold.appendChild(document.createTextNode(wordTab25[i]));
      nn.appendChild(bold);
      var cats = sp3 + "unbekannt";
      if (wordCat.hasOwnProperty(wordTab25[i])) {
        cats = sp3 + wordCat[wordTab25[i]].join(' | ');
      }
      nn.appendChild(document.createTextNode(cats));
      nn.appendChild(document.createElement("BR"));
    }
    element.parentNode.replaceChild(nn, element);
  }
}


// Die nicht versteckten Kategorien der Einträge verarbeiten
function handleResponseCats(data) {
  if (data.query !== undefined && data.query.pages !== undefined) {
    wordCat = {};
    var sname = "";
    var langcnt = {};   // Counter für Sprachzugehörigkeit
    var dqp = data.query.pages;
    for (var i in dqp) {
      if (dqp[i].hasOwnProperty("categories")) {
        var dqpc = dqp[i].categories;
        wordCat[dqp[i].title] = [];
        for (var cat = 0; cat < dqpc.length; cat++) {
          if (dqpc[cat].title.indexOf("Übersetzung") >= 0) {continue;}
          wordCat[dqp[i].title].push(dqpc[cat].title.substring(10));  // ohne "Kategorie:" Präfix
          var lang = dqpc[cat].title.match(/\([^)]+\)/g);  // Text, der in Klammern steht
          if (lang) {
            sname = lang[0].slice(1,lang[0].length-1);
            if (langcnt.hasOwnProperty(sname)) {
              langcnt[sname]++;
            } else {
             langcnt[sname] = 1;
            }
          }
        }
      }
    }

// Sprachzugehörigkeit anhand der Häufigkeit ermitteln
    var maxlang = 0;
    var maxname = "unbekannt";
    for (var i in langcnt) {
      if (langcnt[i] > maxlang) {
        maxlang = langcnt[i];
        maxname = i;
        sprachname = i;
      }
    }

// Ergebnis in GUI setzen
    document.getElementById("sprache").innerHTML =
      '<a href="#MLSprache" onclick="foMoreLinks.doDetailsSprache();">Sprache</a>: ' +
      '<a href="#" onclick="foMoreLinks.doDetailsSprache();return false;">' + maxname + '</a>';
  }
}


// Die Sprach-Kategorie der Einträge verarbeiten; nach der Suche nach einzelner Sprache
// Ergebnis per requestid den einzelnen Abschnitten zuordnen
function handleResponseCats1(data) {

  if (data.query !== undefined && data.query.pages !== undefined) {

    var dqp = data.query.pages;
    var idx = parseInt(data.requestid.slice(1));
    for (var i in dqp) {
      if ( dqp[i].hasOwnProperty("pageid")) {   // Seite ist vorhanden
        if ( ! dqp[i].hasOwnProperty("categories")) {   // aber Kategorie fehlt, dann gelb markieren
          $(bspTab[idx].element).find("A").each(function(index, element) {
            // Abfrage auf href wegen rot/blau Links; "$", damit kein prefix matched
            if ((element.href+"$").indexOf("title=" + mw.util.wikiUrlencode(dqp[i].title) + "$") >= 0) {
              element.style.backgroundColor = "yellow";
            }
          });
        }
      }
    }

  }
}


// Die Sprach-Kategorie der Einträge verarbeiten; nach der Suche nach einzelner Sprache
// Ergebnis per requestid den einzelnen Abschnitten zuordnen
function handleResponseCats2(data) {
debugger;
  if (data.query !== undefined && data.query.pages !== undefined) {

    var dqp = data.query.pages;
    for (var i in dqp) {
      if ( dqp[i].hasOwnProperty("pageid")) {   // Seite ist vorhanden
        if ( ! dqp[i].hasOwnProperty("categories")) {   // aber Kategorie fehlt, dann gelb markieren
          $("#MLoutput").find("A").each(function(index, element) {
            // Abfrage auf href wegen rot/blau Links; "$", damit kein prefix matched
            if ((element.href+"$").indexOf("title=" + mw.util.wikiUrlencode(dqp[i].title) + "$") >= 0) {
              element.style.backgroundColor = "yellow";
            }
          });
        }
      }
    }

  }
}


// Die Ergebnisse der exists-Abfrage den einzelnen Wörtern zuordnen
function handleResponseLinks(data) {
  if (data.parse !== undefined && data.parse.links !== undefined) {
    inputWords  = {};
    var dpl = data.parse.links;

    for (var i = dpl.length - 1; i >= 0; i--) {
      var t = dpl[i]['*'];
      if (dpl[i].hasOwnProperty("exists") && t.length > 0) {
        inputWords[t] = true;
      }
    }

    var element = document.getElementById("MLoutput");  // Auf welcher Seite bin ich?
    if (element) {                                      // Auf "Was noch fehlt"
      var nn = element.cloneNode(false);
      statb = 0;
      stata = 0;
      statu = 0;
      markiereText(inputWords,element,nn,"red");
      var summe = statb + stata + statu;
      var comment = "";
      if (summe > 100) {
        var comment = sp3 + "Puh, das waren aber viele Wörter!";
      }
      document.getElementById("MLw").textContent = 
        "Wörter: "+summe+sp3+"Bekannte Wörter: "+statb+" ("+(statb * 100 / summe).toFixed(2)+
        " %)"+sp3+"Abweichende Großschreibung: "+stata+" ("+(stata * 100 / summe).toFixed(2)+
        " %)";
      document.getElementById("MLuw").textContent = 
        " "+statu+" ("+(statu * 100 / summe).toFixed(2)+" %)" + comment;
      $("#MLStatistik").show();
      $("#MLDetails").show();
    } else if (mw.config.get("wgNamespaceNumber") == 108) {  // Im Flexionsnamensraum (Verben)
      $("#mw-content-text").find("TD").each(function(index, element) {
        var nn = element.cloneNode(false);
        markiereText(inputWords,element,nn,"black");
      });
    } else {       // Im Eintragsnamensraum Bedeutungen und Beispiele
      $(pBeddl).add(pBspdl).find("DD").each(function(index, element) {
        var nn = document.createElement("DD");
        markiereText(inputWords,element,nn,"red");
      });
      // Sprachzugehörigkeit testen
      //if (mw.config.get("wgUserName") == "Formatierer") {
        _public.doCheck1();
      //}
    }
 
  }
}


function markiereText(words,element,nn,color) {

  var i = 0, j = 0, k = 0;
  while ( i < element.childNodes.length) {

    var nv = element.childNodes[i].nodeValue;
    if (nv) {  // textnode
      var w = '';
      var wt = '';

      if (i == 0) { // strip off first [n]
        k = nv.indexOf(']');
        if (k < 0 || k > 7) {
          k = 0;
        } else {
          k++;
          newText(nn,nv.slice(0,k),"black");
        }
      } else {
        k = 0;
      }

      for (j = k; j < nv.length; j++) {
        if (isAllowed(nv.charAt(j))) {
          w += nv.charAt(j);
        } else {
          wt = markiereWort(words,wt,w,nn,color);
          w = '';
          wt = wt + nv.charAt(j);
        }
      }
      wt = markiereWort(words,wt,w,nn,color);
      if (wt.length > 0) {
        newText(nn,wt,color);
      }
      i++;
    } else {
      nn.appendChild(element.childNodes[i]);
    }
  }
  if (nn != null) {
    element.parentNode.replaceChild(nn, element);
  }

}


function markiereWort(words,wt,w,nn,color) {
  if (w.length > 0) {
    if (words.hasOwnProperty(w)) {
      newText(nn,wt,color);
      newLink(nn,w);
      wt = '';
      statb++;
      wordb.push(w);
    } else if (words.hasOwnProperty(toLower1(w))) {
      newText(nn,wt,color);
      newLinkGk(nn,w);
      wt = '';
      stata++;
      worda.push(w);
    } else {
      wt = wt + w;
      statu++;
      wordu.push(w);
    }
  }
  return wt;
}


// Api-Aufruf starten, wenn 50 Titel erreicht oder
// wenn t == null, dann txt aus Puffer
function limit50(t,idx,sprache,func){
 if (t) {
  if (limitCnt == 0) {
   limitTxt += t;
  } else {
   limitTxt += "|"+t;
  }
  limitCnt++;
 }

 if (limitCnt == 50 || t == null) {
  if (limitTxt.length > 0) {
   $.get(buildApi(limitTxt,"action=query&format=json&requestid=i" + idx +
     "&prop=categories&cllimit=5000&clcategories=" + mw.util.wikiUrlencode("Category:" + sprache) +
     "&titles="),func);
  }
  limitTxt = '';
  limitCnt = 0;
 }
}


// Die Wörter eines Abschnitts ermitteln, dabei eventuell am Anfang des Textes vorhandenes
// Bedeutungskürzel entfernen
function getWords(element) {
  var txt = '';
  var i,k;
  for (i = 0; i < element.childNodes.length; i++) {
    var nv = element.childNodes[i].nodeValue;
    if (nv) {
      if (i == 0) { // strip off first [n]
        k = nv.indexOf(']');
        if (k < 0 || k > 7) {
          k = 0;
        } else {
          k++;
        }
      } else {
        k = 0;
      }
      
      txt += getWordsFromText(nv.slice(k),0);
    }
  }
  return txt;
}


// beliebige Anzahl für max <= 0; sonst max
function getWordsFromText(input,max) {
  var w = '';
  var txt = '';

  for (var j = 0; j < input.length; j++) {

    if (isAllowed(input.charAt(j))) {
      w += input.charAt(j);
    } else {
      txt += wikiLink(w);
      w = '';
      max--;
      if (max == 0) { return txt; }
    }
  }
  txt += wikiLink(w);
  return txt;
}


// Tabelle der Wörter in input; beliebige Anzahl für max <= 0; sonst max
function getWordTabFromText(input,max) {
  var w = '';
  var tab = [];
  var chr1 = '';

  for (var j = 0; j < input.length; j++) {
    chr1 = input.charAt(j);
    if (isAllowed(chr1)) {
      w += chr1;
    } else {
      if (w.length > 0) {
        tab.push(w);
        max--;
        if (max == 0) { return tab; }
      }
      w = '';
    }
  }
  if (w.length > 0) {
    tab.push(w);
  }
  return tab;
}


function wikiLink(w) {
  var t = '';
  if (w.length > 0) {
    t += "[[" + w + "]]";
    if (w.charAt(0) == w.charAt(0).toUpperCase()) {
      t += "[[" + toLower1(w) + "]]";
    }
  }
  return t;
}


// Parameterliste aus w erstellen; bei grossem Wort auch "|Wort|wort"
function wikiList(w) {
  var t = '';
  if (w.length > 0) {
    t += "|" + w;
    if (w.charAt(0) == w.charAt(0).toUpperCase()) {
      t += "|" + toLower1(w);
    }
  }
  return t;
}


function toLower1(w) {
  return w.charAt(0).toLowerCase() + w.slice(1);
}


function toUpper1(w) {
  return w.charAt(0).toUpperCase() + w.slice(1);
}


function newLink(nn,t) {
  var nl = document.createElement("a");
  nl.href = buildUrl2(t,"");
  nl.innerHTML = t;
  nn.appendChild(nl);
}


function newLinkRed(nn,t) {
  var nl = document.createElement("a");
  nl.href = buildUrl2(t, "&action=edit&redlink=1");
  nl.classList.add("new");
  nl.innerHTML = t;
  nn.appendChild(nl);
}


function newLinkGk(nn,t) {
  var nl = document.createElement("a");
  var ns = document.createElement("SPAN");
  ns.style.color = "red";
  ns.appendChild(document.createTextNode(t.charAt(0)));
  nl.href = buildUrl2(toLower1(t),"");
  nl.appendChild(ns);
  nl.appendChild(document.createTextNode(t.slice(1)));
  nn.appendChild(nl);
}


function newText(nn,t,color) {
  if (t.length == 0) return;
  if (t == ' ') {
    nn.appendChild(document.createTextNode(t));
    return;
  }
  var ns = document.createElement("SPAN");
  ns.style.color = color;
  var nt = document.createTextNode(t);
  ns.appendChild(nt); 
  nn.appendChild(ns);
}


function isAllowed(c) {
  return c.toLowerCase() != c.toUpperCase() || /[ß0-9\-]/.test(c);
}


function addCORS() {
 if (window.location.hostname.indexOf(".m.") >= 0) {  // mobile site
  return "origin=" + window.location.protocol + "//" + window.location.hostname + "&";
 }
 return "";
}

function getServer() {
 var server = mw.config.get("wgServer");
 if (window.location.hostname.indexOf(".m.") >= 0) {  // mobile site
  if (server.indexOf(".m.") < 0) {
   return server.replace(".", ".m.");
  }
 }
 return server;
}

function buildApi(t,p) {
 return getServer() + mw.config.get("wgScriptPath") + "/api.php?" + addCORS() +
        p + mw.util.wikiUrlencode(t);
}

function buildUrl2(t,p) {
 return getServer() + mw.config.get("wgScript") + "?title=" + mw.util.wikiUrlencode(t) + p;
}


// end namespace: foMoreLinks
}( window.foMoreLinks = window.foMoreLinks || {}, jQuery ));


if (mw.config.get("wgAction") == "view") {
  if (mw.config.get("wgNamespaceNumber") == 0) {
    jQuery(document).ready(foMoreLinks.init);
  } else if (mw.config.get("wgNamespaceNumber") == 108) {
    jQuery(document).ready(foMoreLinks.doCheck108);
  } else if (mw.config.get("wgArticleId") == 1058051) {
    jQuery(document).ready(foMoreLinks.initCheck);
  }
}


//</nowiki>