/* $Id: css_inherit.js,v 1.3 2005/12/12 17:31:18 short Exp $
 * JavaScript helper for CSS 'subroutines'.
 * Copyright (C) 2005 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; exactly version 2 of June 1991 is required
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


// Required CSS rule syntax: .PARENTNAME XXX[-lace-inherit="CHILDNAME"] { }
// Be aware: CSS is case insensitive but HTML/XHTML is (sometimes?) sensitive.
// Be aware: Works only on CSS directly applied by the "class" attribute!
// TODO: Warns on invalid inheritance rules.

// Double-run protection due to the My::Web "text/javascript" compatibility hack.
if (!window.var_My_css_inherit_done++) {
	var var_My_css_inherit_done=1;

var map;

function map_set(from,to)
{
	if (!map)
		map=new Array();
	if (!map[from])
		map[from]=new Array();
	if (map[from][to])
		return true;
	map[from][to]=true;
	return false;
}

function css_inherit_node(node)
{
	if (node.className) {
		var classone_re=node.className.toLowerCase().match(/(\S+)/g);
		for (var classonei in classone_re) {
			var classone=classone_re[classonei];
			if (!map || !map[classone])
				continue;
			for (var target in map[classone])
				node.className+=" "+target;
			}
		}
	for (node=node.firstChild;node!=null;node=node.nextSibling)
		css_inherit_node(node);
}

function css_inherit()
{
	if (document.styleSheets)
		for (var stylei in document.styleSheets) {
			var style=document.styleSheets[stylei];
			if (!style.cssRules)
				continue;
			for (var rulei in style.cssRules) {
				var rule=style.cssRules[rulei];
				if (!rule.selectorText)
					continue;
				var re;
				if (!(re=rule.selectorText.toLowerCase()
						.match(/^\s*[.]([-\w]+).*\[\s*-lace-inherit\s*=\s*"?([^"]*)"?\s*\]\s*/)))
					continue;
				var from_string=re[1];
				var to_string=re[2];
				var to_re=to_string.match(/\S+/g);
				for (var to_rei in to_re) {
					var to_item=to_re[to_rei];
					map_set(from_string,to_item);
					}
				}
			}
	var change;
	do {
		change=false;
		for (var from in map)
			for (var to in map[from]) {
				if (!map[to])
					continue;
				for (var filler in map[to])
					if (!map_set(from,filler))
						change=true;
				}
		} while (change);
	/* Gecko: document.createNodeIterator(...)==NS_ERROR_NOT_IMPLEMENTED */
	css_inherit_node(document);
}

/* Origin: http://simon.incutio.com/archive/2004/05/26/addLoadEvent */
function addLoadEvent(func)
{
	var onload_orig=window.onload;
	if (typeof(onload_orig)!='function')
		window.onload = func;
	else
		window.onload = function()
		{
			onload_orig();
			func();
		};
}

addLoadEvent(css_inherit);

}
