User:Skinbastler~commonswiki/myskin.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/** find an element in document by its id */
function $(id) {
	return document.getElementById(id);
}
 
/** executes a function when the DOM is loaded */
function doOnDOMContentLoaded(func) {
	window.addEventListener("DOMContentLoaded", func, false);
}
 
//--------------------------------------------------------------------------------
 
function asArray(inp) {
	var	out	= [];
	for (var i=0; i<inp.length; i++)	out.push(inp[i]);
	return out;
}
 
function clear(el) {
	while (el.lastChild)	
			el.removeChild(
					el.lastChild);
}
 
function move(src, dst) {
	while (src.firstChild)
			dst.appendChild(
					src.removeChild(
							src.firstChild))
}
 
function replace(src, dst) {
	clear(dst);
	move(src, dst);
}
 
//--------------------------------------------------------------------------------
 
/** synchronous loading of an URLs content */
function load(url) {
	var	client	= new XMLHttpRequest();
	client.open("GET", url, false);
	client.send(null);
	return client.responseText;
}
 
/** parse an HTML DOM */
function parseDOM(text) {
	var	doc		= new DOMParser().parseFromString(text, "text/xml");
	var	root	= doc.documentElement;
	// root.namespaceURI == "http://www.mozilla.org/newlayout/xml/parsererror.xml"
	if (root.tagName == "parserError")
			throw "XML parser error: " + root.textContent;
	return doc;
}
 
 
/** activate a new stylesheet */
function loadStyleSheet(url) {
	var	text	= load(url);
	var link	= document.createElement("link");
	link.setAttribute("href", url);
	link.setAttribute("rel", "stylesheet");
	document.getElementsByTagName("head")[0].appendChild(link);
	link.text = text;
}
 
//--------------------------------------------------------------------------------
 
function stealLang(srcBody, dstBody) {
	var	srcPortlet	= srcBody.ownerDocument.getElementById("p-lang");
	var	dstPortlet	= dstBody.ownerDocument.getElementById("p-lang");
	if (!srcPortlet || !dstPortlet) {
		clear(dstPortlet);
		return;
	}
	var	srcTag	= srcPortlet.getElementsByTagName("ul")[0];
	var	dstTag	= dstPortlet.getElementsByTagName("ul")[0];
	if (!srcTag || !dstTag) {
		clear(dstPortlet);
		return;
	}
	move(srcTag, dstTag);
}
 
function stealAll(srcBody, dstBody) {
	asArray(dstBody.getElementsByTagName("a"))
			.filter(function(a) { return a.getAttribute("steal") != null; })
			.forEach(function(a) { stealOne(srcBody, a.getAttribute("steal"), a); });
}
 
function stealOne(srcBody, srcQuery, dstLink) {
	var	src	= srcBody.ownerDocument.getElementById(srcQuery);
	if (src)	{
		var	as	= src.getElementsByTagName("a");
		if (as.length > 0) {
			var	a				= as[0];
			dstLink.href		= a.href;
			dstLink.title		= a.title;
			dstLink.innerHTML	= a.innerHTML;
			return;
		}
	}
	dstLink.parentNode.removeChild(dstLink);
}
 
/** replaces the skin with loaded code */
function replaceSkin(htmlURL, cssURL) {
	// install stylesheet
	loadStyleSheet(cssURL);
 
	// load ffm code
	var	html	= load(htmlURL);
	var	dom		= parseDOM(html);
 
	// extract myskin page content
	var	extract	= /^.*<!-- start content -->\s*(.*)\s*<!-- end content -->.*$/;
	var	content	= $('content').innerHTML.replace(extract, "$1");
 
	var	ffm		= dom.getElementsByTagName("body")[0];
	var	myskin	= document.body;
 
	// modify ffm with data from myskin
	stealLang(myskin, ffm);
	stealAll(myskin, ffm);
 
	// replace myskin body
	replace(ffm, myskin);
 
	// revert content to myskin's
	$('content').innerHTML	= content;
}
 
doOnDOMContentLoaded(function() {
	replaceSkin(
			"http://commons.wikimedia.org/wiki/User:Skinbastler/html?action=raw",
			"http://commons.wikimedia.org/wiki/User:Skinbastler/css?action=raw&ctype=text/css");
});