+&text_cc: Country-dependent static text chooser.
[MyWeb.git] / css_inherit.js
1 /* $Id$
2  * JavaScript helper for CSS 'subroutines'.
3  * Copyright (C) 2005 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 // Required CSS rule syntax: .PARENTNAME XXX[-lace-inherit="CHILDNAME"] { }
21 // Be aware: CSS is case insensitive but HTML/XHTML is (sometimes?) sensitive.
22 // Be aware: Works only on CSS directly applied by the "class" attribute!
23 // TODO: Warns on invalid inheritance rules.
24
25 // Double-run protection due to the My::Web "text/javascript" compatibility hack.
26 if (!window.var_My_css_inherit_done++) {
27         var var_My_css_inherit_done=1;
28
29 var map;
30
31 function map_set(from,to)
32 {
33         if (!map)
34                 map=new Array();
35         if (!map[from])
36                 map[from]=new Array();
37         if (map[from][to])
38                 return true;
39         map[from][to]=true;
40         return false;
41 }
42
43 function css_inherit_node(node)
44 {
45         if (node.className) {
46                 var classone_re=node.className.toLowerCase().match(/(\S+)/g);
47                 for (var classonei in classone_re) {
48                         var classone=classone_re[classonei];
49                         if (!map || !map[classone])
50                                 continue;
51                         for (var target in map[classone])
52                                 node.className+=" "+target;
53                         }
54                 }
55         for (node=node.firstChild;node!=null;node=node.nextSibling)
56                 css_inherit_node(node);
57 }
58
59 function css_inherit()
60 {
61         if (document.styleSheets)
62                 for (var stylei in document.styleSheets) {
63                         var style=document.styleSheets[stylei];
64                         if (!style.cssRules)
65                                 continue;
66                         for (var rulei in style.cssRules) {
67                                 var rule=style.cssRules[rulei];
68                                 if (!rule.selectorText)
69                                         continue;
70                                 var re;
71                                 if (!(re=rule.selectorText.toLowerCase()
72                                                 .match(/^\s*[.]([-\w]+).*\[\s*-lace-inherit\s*=\s*"?([^"]*)"?\s*\]\s*/)))
73                                         continue;
74                                 var from_string=re[1];
75                                 var to_string=re[2];
76                                 var to_re=to_string.match(/\S+/g);
77                                 for (var to_rei in to_re) {
78                                         var to_item=to_re[to_rei];
79                                         map_set(from_string,to_item);
80                                         }
81                                 }
82                         }
83         var change;
84         do {
85                 change=false;
86                 for (var from in map)
87                         for (var to in map[from]) {
88                                 if (!map[to])
89                                         continue;
90                                 for (var filler in map[to])
91                                         if (!map_set(from,filler))
92                                                 change=true;
93                                 }
94                 } while (change);
95         /* Gecko: document.createNodeIterator(...)==NS_ERROR_NOT_IMPLEMENTED */
96         css_inherit_node(document);
97 }
98
99 /* Origin: http://simon.incutio.com/archive/2004/05/26/addLoadEvent */
100 function addLoadEvent(func)
101 {
102         var onload_orig=window.onload;
103         if (typeof(onload_orig)!='function')
104                 window.onload = func;
105         else
106                 window.onload = function()
107                 {
108                         onload_orig();
109                         func();
110                 };
111 }
112
113 addLoadEvent(css_inherit);
114
115 }