User:Dbenzhuser/showRedundantLinks.js

/* * 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 markiert. * 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. var linkNodes = new Array; // Mergesort für Arrays // Wegen kleiner Modifikationen (siehe Kommentare) nur zur Verwendung bei der // Erstellung der Linkleiste. 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[i++]=this[j++]; }		var i=0; var k=lo; while (k<j && j<=hi) { // Sortiert wird nach Title-Attribut der Links. // '[0].getAttribute("title")' entfernen für normalen Mergesort. if (b[i][0].getAttribute("title")<=this[j][0].getAttribute("title")) { this[k++]=b[i++]; }			else { this[k++]=this[j++]; }		}		while (k<j) { this[k++]=b[i++]; }	} } // 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[i].className.search(reg) != -1) { if(on) { // objects[i].addAttributeValue("class", "highlight"); objects[i].style.backgroundColor = "#ffaa00"; }			else { // objects[i].removeAttributeValue("class", "highlight"); objects[i].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 h5 = document.createElement("h5"); var h5Text = document.createTextNode("Links in article"); var divPbody = document.createElement("div"); var ul = document.createElement("ul"); // Mit Attributen ausrüsten. divPortlet.setAttribute("id", "p-link"); divPortlet.setAttribute("class", "portlet"); divPbody.setAttribute("class", "pBody"); ul.setAttribute("id", "u-link") // Spalte suchen. var column = document.getElementById("column-one"); // Box einbauen. column.appendChild(divPortlet); divPortlet.appendChild(h5); h5.appendChild(h5Text); 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("Enable!"); 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[i].getAttribute("title") && !regexpExclude.test(links[i].getAttribute("href")) && (regexpExist.test(links[i].getAttribute("href")) || regexpNotExist.test(links[i].getAttribute("href")))) { linkNodes.push(new Array(links[i].cloneNode(true), links[i])); }	}	// 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[i][0].getAttribute("title"); var linkText = document.createTextNode(linkTitle); linkNodes[i][0].replaceChild(linkText, linkNodes[i][0].firstChild); // Attribute und Funktionsaufrufe für Highlighting. // Leerzeichen werden durch Unterstriche ersetzt. var linkTitleClass = linkTitle; linkTitleClass = linkTitleClass.replace(/\s/g, "_"); linkNodes[i][0].addAttributeValue("class", linkTitleClass); linkNodes[i][0].setAttribute("onmouseover", "highlight(\""+linkTitleClass+"\", true)"); linkNodes[i][0].setAttribute("onmouseout", "highlight(\""+linkTitleClass+"\", false)"); linkNodes[i][1].addAttributeValue("class", linkTitleClass); linkNodes[i][1].setAttribute("onmouseover", "highlight(\""+linkTitleClass+"\", true)"); linkNodes[i][1].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[i][0].firstChild.nodeValue == linkNodes[i-j][0].firstChild.nodeValue)) { j++; }			else { equal = false; // Nur bei mehrfachvorkommenden Links Zähler einfügen. if (j != 1) { var span = document.createElement("span"); linkNodes[i][1].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[i][0]); } } // onload $(createLinksSidebar); /* * Ende showRedundantLinks */