// ==UserScript==
// @name          Wikipedia linked section headers
// @namespace     http://henrik.nyh.se
// @description   Makes Wikipedia sections headers into anchor links to themselves, for easier copying/bookmarking of such links.
// @include       http://*.mediawiki.org/wiki/*
// @include       http://wikimediafoundation.org/wiki/*
// @include       http://*.wik*.org/wiki/*
// @include       http://*.wikia.com/wiki/*
// @include       http://*uncyclopedia.org/wiki/*
// @include       http://wiki.mozilla.org/*
// @include       http://developer.mozilla.org/*/docs/*
// @include       http://kb.mozillazine.org/*
// @include       http://wiki.greasespot.net/*
// ==/UserScript==

var anchors = '//a[@name][not(@name="top")]';
var relative_header = 'ancestor::p/following-sibling::node()/span[@class="mw-headline"]';
var absolute_header = 'following-sibling::node()';

var header, link;
with_each(anchors, function(anchor) {
	header = $x(relative_header, anchor)[0] || $x(absolute_header, anchor)[0];
	link = document.createElement("a");
	link.href = "#" + (anchor.id || anchor.name);
	link.className = "gm-uso-anchor"; // for css
	link.appendChild(document.createTextNode("#"));
	if (header.nodeName == "span")
		header.parentNode.appendChild(link);
	else // mediawiki v1.8.* or below
		header.appendChild(link);
});

function $x(xpath, root) {
	var doc = root ? root.evaluate ? root : root.ownerDocument : document, next;
	var got = doc.evaluate(xpath, root||doc, null, null, null), result = [];
	while(next = got.iterateNext())
		result.push(next);
	return result;
}
function with_each(xpath, cb, root) {
	var results = $x(xpath, root);
	for (var i = 0, j = results.length; i < j; i++)
		cb(results[i]);
}

GM_addStyle(".gm-uso-anchor {\n\
  visibility: hidden;\n\
  opacity: .25;\n\
  margin-left: .25em;\n}\n\
h1:hover .gm-uso-anchor,\n\
h2:hover .gm-uso-anchor,\n\
h3:hover .gm-uso-anchor,\n\
h4:hover .gm-uso-anchor,\n\
h5:hover .gm-uso-anchor,\n\
h6:hover .gm-uso-anchor {\n\
  visibility: visible;\n}");

