/*
* showRedundantLinks
* In der Navigationsleiste am Rand wird eine sortierte Liste aller im Artikel
* vorkommenden Links erstellt. Mehrfach vorkommende Links werden im Artikel
* gekennzeichnet.
* Beim Überfahren von Links mit der Maus werden alle Vorkommen des
* entsprechenden Links mit der Klasse "highlight" ausgestattet. Dies kann mit
* CSS sichtbar gemacht werden (siehe de:Benutzer:Dbenzhuser/monobook.css für
* ein Beispiel).
* Ziel ist es auch bei längeren Artikeln leicht mehrfach vorkommende Links
* ausfindig zu machen.
* Scheint bislang nur mit Gecko-Browsern zu funktionieren.
* Anmerkungen, Verbesserungen, Hinweise, Nörgeleien jederzeit gerne gesehen!
* dbenzhuser (de:Benutzer:Dbenzhuser)
*/
// Zutun: Links an der Seite mit Sonderfunktionen belegen.
// Z.B. dauerhaft markieren, Sprung zu Link.
// Mergesort für Arrays
// Wegen kleiner Modifikationen (siehe Kommentare) nur zur Verwendung bei der
// Erstellung der Linkleiste.
var linkNodes = new Array();
var b;
linkNodes.mergesort = function(lo, hi) {
if (lo<hi) {
var mid = ((hi+lo)-(hi+lo)%2) / 2;
this.mergesort(lo, mid);
this.mergesort(mid+1, hi);
var i=0;
var j=lo;
while (j<=mid) {
b=this;
}
var i=0;
var k=lo;
while (k<j && j<=hi) {
// Sortiert wird nach Title-Attribut der Links.
// '.getAttribute("title")' entfernen für normalen Mergesort.
if (b.getAttribute("title")<=this.getAttribute("title")) {
this=b;
}
else {
this=this;
}
}
while (k<j) {
this=b;
}
}
}
// Fügt einem Attribut einen weiteren durch Leerzeichen abgetrennten Wert hinzu.
Node.prototype.addAttributeValue = function(key, value) {
if (!this.getAttribute(key)) {
this.setAttribute(key, value);
}
else {
this.setAttribute(key, this.getAttribute(key)+ " " +value);
}
}
// Löscht einen Wert aus einem Attribut.
Node.prototype.removeAttributeValue = function(key, value) {
var newvalue = this.getAttribute(key);
var reg = new RegExp("(^|\\s)"+value+"(\\s|$)");
newvalue = newvalue.replace(reg, " ");
newvalue = newvalue.replace(/^\s+/g, "");
newvalue = newvalue.replace(/\s+$/g, "");
this.setAttribute(key, newvalue);
}
// Markierungen werden bei allen Links der übergebenen Klasse ein bzw ausgeblendet.
function highlight(cname, on) {
var objects = document.getElementsByTagName("a");
cname = cname.replace("(", "\\(");
cname = cname.replace(")", "\\)");
var reg = new RegExp("(^|\\s)"+cname+"(\\s|$)");
var length = objects.length
for(var i = 0; i < length; i++) {
if(objects.className.search(reg) != -1) {
if(on) {
// objects.addAttributeValue("class", "highlight");
objects.style.backgroundColor = "#ffaa00";
}
else {
// objects.removeAttributeValue("class", "highlight");
objects.style.backgroundColor = "transparent";
}
}
}
}
// Nach dem Vorbild der bereits vorhandenen Listen wird eine neue Box in der
// Navigationsleiste installiert, die einen Link zum Aktivieren des
// Linksammlers enthält.
function createLinksSidebar() {
// Elemente der Box erstellen.
var divPortlet = document.createElement("div");
var h3 = document.createElement("h3");
var h3Text = document.createTextNode("Links im Artikel");
var divPbody = document.createElement("div");
var ul = document.createElement("ul");
// Mit Attributen ausrüsten.
divPortlet.id = "p-link";
divPortlet.className = "portlet portal";
divPbody.className = "pBody body";
ul.id = "u-link";
// Spalte suchen.
var column = document.getElementById("column-one") || document.getElementById("mw-panel");
// Box einbauen.
column.appendChild(divPortlet);
divPortlet.appendChild(h3);
h3.appendChild(h3Text);
divPortlet.appendChild(divPbody);
divPbody.appendChild(ul);
// Aktivierunglink erstellen.
var li = document.createElement("li");
li.style.whiteSpace = "nowrap";
ul.appendChild(li);
var a = document.createElement("a");
a.setAttribute("href", "javascript:showRedundantLinks()");
a.setAttribute("title", "Aktivieren!");
li.appendChild(a);
var aText = document.createTextNode("Aktivieren");
a.appendChild(aText);
}
// Alle Wikilinks innerhalb des Artikels werden gesammelt.
// Anschließend werden sie in der Liste angezeigt und mehrfache Links im
// Artikeltext markiert.
function showRedundantLinks() {
// "Aktivieren"-Link (inkl Listenelement) entfernen.
var ul = document.getElementById("u-link");
ul.removeChild(ul.firstChild);
// Alle Links im Artikeltext sammeln.
var links = document.getElementById("bodyContent").getElementsByTagName("a");
// Regexps zur Bestimmung der relevanten Links.
var regexpExist = /^\/wiki\/(.+)$/;
var regexpNotExist = /^\/w\/index\.php\?title=(.+)\&action=edit$/;
var regexpExclude = /^\/w(iki)?\/(index\.php\?title=)?(Bild|Benutzer|Benutzer_Diskussion)\:(.+)$/;
// Nur relevante Links in neues Array speichern.
// Dabei werden jeweils eine Referenz auf den Link im Artikel und ein Klon
// für die Linkleiste gespeichert.
var linkCount1 = links.length;
for (var i=0; i < linkCount1; ++i) {
if (links.getAttribute("title") && !regexpExclude.test(links.getAttribute("href")) && (regexpExist.test(links.getAttribute("href")) || regexpNotExist.test(links.getAttribute("href")))) {
linkNodes.push(new Array(links.cloneNode(true), links));
}
}
// Bei Links für Linkleiste den Linktext mit Title-Attribut überschreiben.
var linkCount2 = linkNodes.length;
for (var i=0; i < linkCount2; ++i) {
var linkTitle = linkNodes.getAttribute("title");
var linkText = document.createTextNode(linkTitle);
linkNodes.replaceChild(linkText, linkNodes.firstChild);
// Attribute und Funktionsaufrufe für Highlighting.
// Leerzeichen werden durch Unterstriche ersetzt.
var linkTitleClass = linkTitle;
linkTitleClass = linkTitleClass.replace(/\s/g, "_");
linkNodes.addAttributeValue("class", linkTitleClass);
linkNodes.setAttribute("onmouseover", "highlight(\""+linkTitleClass+"\", true)");
linkNodes.setAttribute("onmouseout", "highlight(\""+linkTitleClass+"\", false)");
linkNodes.addAttributeValue("class", linkTitleClass);
linkNodes.setAttribute("onmouseover", "highlight(\""+linkTitleClass+"\", true)");
linkNodes.setAttribute("onmouseout", "highlight(\""+linkTitleClass+"\", false)");
}
// Hilfsarray vorbereiten und Sortierungsfunktion aufrufen.
b = new Array(((linkNodes.length)-(linkNodes.length%2))/2);
linkNodes.mergesort(0, linkNodes.length-1);
// Links im Artikeltext mit Zähler ausstatten.
for (var i=1; i < linkCount2; ++i) {
var equal = true;
var j = 1;
while (equal == true) {
if(i >= j && (linkNodes.firstChild.nodeValue == linkNodes.firstChild.nodeValue)) {
j++;
}
else {
equal = false;
// Nur bei mehrfachvorkommenden Links Zähler einfügen.
if (j != 1) {
var span = document.createElement("span");
linkNodes.appendChild(span);
var spanText = document.createTextNode(" (" + j + ")");
span.appendChild(spanText);
// span.setAttribute("class", "redundantLinkMark"); // Klasse für (n).
span.style.color = "green";
span.style.fontWeight = "bold";
}
}
}
}
// Links in Linkleiste schreiben (jeweils mit Listenelement).
for (var i=0; i < linkCount2; ++i) {
var li = document.createElement("li");
ul.appendChild(li);
li.style.whiteSpace = "nowrap";
li.appendChild(linkNodes);
}
}
// onload
$(document).ready(createLinksSidebar);
/*
* Ende showRedundantLinks
*/