newly created node can be declared 'reservable'
[www-register-wizard.git] / rounded.js
1 // Contributors 
2 // Ilkka Huotari at http://www.editsite.net
3 // Mathieu 'p01' HENRI at http://www.p01.org/
4 // http://seky.nahory.net/2005/04/rounded-corners/
5 // Steven Wittens at http://www.acko.net/anti-aliased-nifty-corners
6 // Original Nifty Corners by Alessandro Fulciniti at http://pro.html.it/esempio/nifty/
7 function NiftyCheck() {
8   if(!document.getElementById || !document.createElement) {
9     return false;
10   }
11   var b = navigator.userAgent.toLowerCase();
12   if (b.indexOf("msie 5") > 0 && b.indexOf("opera") == -1) {
13     return false;
14   }
15   return true;
16 }
17
18 function Rounded(className, sizex, sizey, sizex_b, sizey_b) {
19         var bk;
20         if (!NiftyCheck()) return;
21         if (typeof(sizex_b) == 'undefined')
22                 sizex_b = sizex;
23         if (typeof(sizey_b) == 'undefined')
24                 sizey_b = sizey;
25         var v = getElements(className);
26         var l = v.length;
27         for (var i = 0; i < l; i++) {
28                 color = get_current_style(v[i],"background-color","transparent");
29                 bk = get_current_style(v[i].parentNode,"background-color","transparent");
30                 AddRounded(v[i], bk, color, sizex, sizey, true);
31                 AddRounded(v[i], bk, color, sizex_b, sizey_b, false);
32         }
33 }
34
35 Math.sqr = function (x) {
36   return x*x;
37 };
38
39 function Blend(a, b, alpha) {
40
41   var ca = Array(
42     parseInt('0x' + a.substring(1, 3)), 
43     parseInt('0x' + a.substring(3, 5)), 
44     parseInt('0x' + a.substring(5, 7))
45   );
46   var cb = Array(
47     parseInt('0x' + b.substring(1, 3)), 
48     parseInt('0x' + b.substring(3, 5)), 
49     parseInt('0x' + b.substring(5, 7))
50   );
51   return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)
52              + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)
53              + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);
54
55   return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)
56              + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)
57              + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);
58 }
59
60 function AddRounded(el, bk, color, sizex, sizey, top) {
61   if (!sizex && !sizey)
62         return;
63   var i, j;
64   var d = document.createElement("div");
65   d.style.backgroundColor = bk;
66   var lastarc = 0;
67   for (i = 1; i <= sizey; i++) {
68     var coverage, arc2, arc3;
69     // Find intersection of arc with bottom of pixel row
70     arc = Math.sqrt(1.0 - Math.sqr(1.0 - i / sizey)) * sizex;
71     // Calculate how many pixels are bg, fg and blended.
72     var n_bg = sizex - Math.ceil(arc);
73     var n_fg = Math.floor(lastarc);
74     var n_aa = sizex - n_bg - n_fg;
75     // Create pixel row wrapper
76     var x = document.createElement("div");
77     var y = d;
78     x.style.margin = "0px " + n_bg + "px";
79         x.style.height='1px';
80         x.style.overflow='hidden';
81     // Make a wrapper per anti-aliased pixel (at least one)
82     for (j = 1; j <= n_aa; j++) {
83       // Calculate coverage per pixel
84       // (approximates circle by a line within the pixel)
85       if (j == 1) {
86         if (j == n_aa) {
87           // Single pixel
88           coverage = ((arc + lastarc) * .5) - n_fg;
89         }
90         else {
91           // First in a run
92           arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
93           coverage = (arc2 - (sizey - i)) * (arc - n_fg - n_aa + 1) * .5;
94           // Coverage is incorrect. Why?
95           coverage = 0;
96         }
97       }
98       else if (j == n_aa) {
99         // Last in a run
100         arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
101         coverage = 1.0 - (1.0 - (arc2 - (sizey - i))) * (1.0 - (lastarc - n_fg)) * .5;
102       }
103       else {
104         // Middle of a run
105         arc3 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j) / sizex)) * sizey;
106         arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
107         coverage = ((arc2 + arc3) * .5) - (sizey - i);
108       }
109       
110       x.style.backgroundColor = Blend(bk, color, coverage);
111           if (top)
112               y.appendChild(x);
113       else
114               y.insertBefore(x, y.firstChild);
115       y = x;
116       var x = document.createElement("div");
117                 x.style.height='1px';
118                 x.style.overflow='hidden';
119       x.style.margin = "0px 1px";
120     }
121     x.style.backgroundColor = color;
122     if (top)
123             y.appendChild(x);
124     else
125                 y.insertBefore(x, y.firstChild);
126     lastarc = arc;
127   }
128   if (top)
129           el.insertBefore(d, el.firstChild);
130   else
131           el.appendChild(d);
132 }
133
134 function getElements(className) {
135         var elements = [];
136         var el = document.getElementsByTagName('DIV');  
137         var regexp=new RegExp("\\b"+className+"\\b");
138         for (var i = 0; i < el.length; i++) 
139         {
140                 if (regexp.test(el[i].className)) 
141                         elements.push(el[i]);
142         }
143         return elements;
144 }
145
146 function get_current_style(element,property,not_accepted)
147 {
148   var ee,i,val,apr;
149   try
150   {
151     var cs=document.defaultView.getComputedStyle(element,'');
152     val=cs.getPropertyValue(property);
153   }
154   catch(ee)
155   {
156     if(element.currentStyle)
157         {
158             apr=property.split("-");
159             for(i=1;i<apr.length;i++) apr[i]=apr[i].toUpperCase();
160             apr=apr.join("");
161             val=element.currentStyle.getAttribute(apr);
162    }
163   }
164   if((val.indexOf("rgba") > -1 || val==not_accepted) && element.parentNode)
165   {
166          if(element.parentNode != document) 
167                  val=get_current_style(element.parentNode,property,not_accepted);
168          else
169                  val = '#FFFFFF';
170   }
171   if (val.indexOf("rgb") > -1 && val.indexOf("rgba") == -1)
172           val = rgb2hex(val);
173   if (val.length == 4)
174           val = '#'+val.substring(1,1)+val.substring(1,1)+val.substring(2,1)+val.substring(2,1)+val.substring(3,1)+val.substring(3,1);
175   return val;
176 }
177
178 function rgb2hex(value)
179 {
180         var x = 255;
181         var hex = '';
182         var i;
183         var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
184         var array=regexp.exec(value);
185         for(i=1;i<4;i++) hex += ('0'+parseInt(array[i]).toString(16)).slice(-2);
186         return '#'+hex;
187 }