From 3cff9c1c05e572c0e98c02ffa1aa6c3d2fc4dcf5 Mon Sep 17 00:00:00 2001 From: short <> Date: Thu, 15 Sep 2005 03:25:34 +0000 Subject: [PATCH] Provide CSS inheritance hack. - How it should be done for CSS officially? --- css_inherit.js | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 css_inherit.js diff --git a/css_inherit.js b/css_inherit.js new file mode 100644 index 0000000..4afea32 --- /dev/null +++ b/css_inherit.js @@ -0,0 +1,109 @@ +/* $Id$ + * JavaScript helper for CSS 'subroutines'. + * Copyright (C) 2005 Jan Kratochvil + * + * 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. + +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); -- 1.8.3.1