]> dev.renevier.net Git - syp.git/blob - openlayers/lib/Rico/Corner.js
fixes notices
[syp.git] / openlayers / lib / Rico / Corner.js
1 /*
2  * This file has been edited substantially from the Rico-released
3  * version by the OpenLayers development team.
4  *  
5  *  Copyright 2005 Sabre Airline Solutions  
6  *  
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the
9  *  License. You may obtain a copy of the License at
10  *  
11  *         http://www.apache.org/licenses/LICENSE-2.0  
12  *  
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the * License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or
16  * implied. See the License for the specific language governing
17  * permissions * and limitations under the License.
18  *
19  */  
20 OpenLayers.Rico = new Object();
21 OpenLayers.Rico.Corner = {
22
23     round: function(e, options) {
24         e = OpenLayers.Util.getElement(e);
25         this._setOptions(options);
26
27         var color = this.options.color;
28         if ( this.options.color == "fromElement" ) {
29             color = this._background(e);
30         }
31         var bgColor = this.options.bgColor;
32         if ( this.options.bgColor == "fromParent" ) {
33             bgColor = this._background(e.offsetParent);
34         }
35         this._roundCornersImpl(e, color, bgColor);
36     },
37
38     /**   This is a helper function to change the background
39     *     color of <div> that has had Rico rounded corners added.
40     *
41     *     It seems we cannot just set the background color for the
42     *     outer <div> so each <span> element used to create the
43     *     corners must have its background color set individually.
44     *
45     * @param {DOM} theDiv - A child of the outer <div> that was
46     *                        supplied to the `round` method.
47     *
48     * @param {String} newColor - The new background color to use.
49     */
50     changeColor: function(theDiv, newColor) {
51    
52         theDiv.style.backgroundColor = newColor;
53
54         var spanElements = theDiv.parentNode.getElementsByTagName("span");
55         
56         for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
57             spanElements[currIdx].style.backgroundColor = newColor;
58         }
59     }, 
60
61
62     /**   This is a helper function to change the background
63     *     opacity of <div> that has had Rico rounded corners added.
64     *
65     *     See changeColor (above) for algorithm explanation
66     *
67     * @param {DOM} theDiv A child of the outer <div> that was
68     *                        supplied to the `round` method.
69     *
70     * @param {int} newOpacity The new opacity to use (0-1).
71     */
72     changeOpacity: function(theDiv, newOpacity) {
73    
74         var mozillaOpacity = newOpacity;
75         var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';
76         
77         theDiv.style.opacity = mozillaOpacity;
78         theDiv.style.filter = ieOpacity;
79
80         var spanElements = theDiv.parentNode.getElementsByTagName("span");
81         
82         for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
83             spanElements[currIdx].style.opacity = mozillaOpacity;
84             spanElements[currIdx].style.filter = ieOpacity;
85         }
86
87     },
88
89     /** this function takes care of redoing the rico cornering
90     *    
91     *    you can't just call updateRicoCorners() again and pass it a 
92     *    new options string. you have to first remove the divs that 
93     *    rico puts on top and below the content div.
94     *
95     * @param {DOM} theDiv - A child of the outer <div> that was
96     *                        supplied to the `round` method.
97     *
98     * @param {Object} options - list of options
99     */
100     reRound: function(theDiv, options) {
101
102         var topRico = theDiv.parentNode.childNodes[0];
103         //theDiv would be theDiv.parentNode.childNodes[1]
104         var bottomRico = theDiv.parentNode.childNodes[2];
105        
106         theDiv.parentNode.removeChild(topRico);
107         theDiv.parentNode.removeChild(bottomRico); 
108
109         this.round(theDiv.parentNode, options);
110     }, 
111
112    _roundCornersImpl: function(e, color, bgColor) {
113       if(this.options.border) {
114          this._renderBorder(e,bgColor);
115       }
116       if(this._isTopRounded()) {
117          this._roundTopCorners(e,color,bgColor);
118       }
119       if(this._isBottomRounded()) {
120          this._roundBottomCorners(e,color,bgColor);
121       }
122    },
123
124    _renderBorder: function(el,bgColor) {
125       var borderValue = "1px solid " + this._borderColor(bgColor);
126       var borderL = "border-left: "  + borderValue;
127       var borderR = "border-right: " + borderValue;
128       var style   = "style='" + borderL + ";" + borderR +  "'";
129       el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>";
130    },
131
132    _roundTopCorners: function(el, color, bgColor) {
133       var corner = this._createCorner(bgColor);
134       for(var i=0 ; i < this.options.numSlices ; i++ ) {
135          corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
136       }
137       el.style.paddingTop = 0;
138       el.insertBefore(corner,el.firstChild);
139    },
140
141    _roundBottomCorners: function(el, color, bgColor) {
142       var corner = this._createCorner(bgColor);
143       for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- ) {
144          corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
145       }
146       el.style.paddingBottom = 0;
147       el.appendChild(corner);
148    },
149
150    _createCorner: function(bgColor) {
151       var corner = document.createElement("div");
152       corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
153       return corner;
154    },
155
156    _createCornerSlice: function(color,bgColor, n, position) {
157       var slice = document.createElement("span");
158
159       var inStyle = slice.style;
160       inStyle.backgroundColor = color;
161       inStyle.display  = "block";
162       inStyle.height   = "1px";
163       inStyle.overflow = "hidden";
164       inStyle.fontSize = "1px";
165
166       var borderColor = this._borderColor(color,bgColor);
167       if ( this.options.border && n == 0 ) {
168          inStyle.borderTopStyle    = "solid";
169          inStyle.borderTopWidth    = "1px";
170          inStyle.borderLeftWidth   = "0px";
171          inStyle.borderRightWidth  = "0px";
172          inStyle.borderBottomWidth = "0px";
173          inStyle.height            = "0px"; // assumes css compliant box model
174          inStyle.borderColor       = borderColor;
175       }
176       else if(borderColor) {
177          inStyle.borderColor = borderColor;
178          inStyle.borderStyle = "solid";
179          inStyle.borderWidth = "0px 1px";
180       }
181
182       if ( !this.options.compact && (n == (this.options.numSlices-1)) ) {
183          inStyle.height = "2px";
184       }
185       this._setMargin(slice, n, position);
186       this._setBorder(slice, n, position);
187       return slice;
188    },
189
190    _setOptions: function(options) {
191       this.options = {
192          corners : "all",
193          color   : "fromElement",
194          bgColor : "fromParent",
195          blend   : true,
196          border  : false,
197          compact : false
198       };
199       OpenLayers.Util.extend(this.options, options || {});
200
201       this.options.numSlices = this.options.compact ? 2 : 4;
202       if ( this._isTransparent() ) {
203          this.options.blend = false;
204       }
205    },
206
207    _whichSideTop: function() {
208       if ( this._hasString(this.options.corners, "all", "top") ) {
209          return "";
210       }
211       if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 ) {
212          return "";
213       }
214       if (this.options.corners.indexOf("tl") >= 0) {
215          return "left";
216       } else if (this.options.corners.indexOf("tr") >= 0) {
217           return "right";
218       }
219       return "";
220    },
221
222    _whichSideBottom: function() {
223       if ( this._hasString(this.options.corners, "all", "bottom") ) {
224          return "";
225       }
226       if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 ) {
227          return "";
228       }
229
230       if(this.options.corners.indexOf("bl") >=0) {
231          return "left";
232       } else if(this.options.corners.indexOf("br")>=0) {
233          return "right";
234       }
235       return "";
236    },
237
238    _borderColor : function(color,bgColor) {
239       if ( color == "transparent" ) {
240          return bgColor;
241       } else if ( this.options.border ) {
242          return this.options.border;
243       } else if ( this.options.blend ) {
244          return this._blend( bgColor, color );
245       } else {
246          return "";
247       }
248    },
249
250
251    _setMargin: function(el, n, corners) {
252       var marginSize = this._marginSize(n);
253       var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
254
255       if ( whichSide == "left" ) {
256          el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
257       }
258       else if ( whichSide == "right" ) {
259          el.style.marginRight = marginSize + "px"; el.style.marginLeft  = "0px";
260       }
261       else {
262          el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
263       }
264    },
265
266    _setBorder: function(el,n,corners) {
267       var borderSize = this._borderSize(n);
268       var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
269       if ( whichSide == "left" ) {
270          el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
271       }
272       else if ( whichSide == "right" ) {
273          el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth  = "0px";
274       }
275       else {
276          el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
277       }
278       if (this.options.border != false) {
279         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
280       }
281    },
282
283    _marginSize: function(n) {
284       if ( this._isTransparent() ) {
285          return 0;
286       }
287       var marginSizes          = [ 5, 3, 2, 1 ];
288       var blendedMarginSizes   = [ 3, 2, 1, 0 ];
289       var compactMarginSizes   = [ 2, 1 ];
290       var smBlendedMarginSizes = [ 1, 0 ];
291
292       if ( this.options.compact && this.options.blend ) {
293          return smBlendedMarginSizes[n];
294       } else if ( this.options.compact ) {
295          return compactMarginSizes[n];
296       } else if ( this.options.blend ) {
297          return blendedMarginSizes[n];
298       } else {
299          return marginSizes[n];
300       }
301    },
302
303    _borderSize: function(n) {
304       var transparentBorderSizes = [ 5, 3, 2, 1 ];
305       var blendedBorderSizes     = [ 2, 1, 1, 1 ];
306       var compactBorderSizes     = [ 1, 0 ];
307       var actualBorderSizes      = [ 0, 2, 0, 0 ];
308
309       if ( this.options.compact && (this.options.blend || this._isTransparent()) ) {
310          return 1;
311       } else if ( this.options.compact ) {
312          return compactBorderSizes[n];
313       } else if ( this.options.blend ) {
314          return blendedBorderSizes[n];
315       } else if ( this.options.border ) {
316          return actualBorderSizes[n];
317       } else if ( this._isTransparent() ) {
318          return transparentBorderSizes[n];
319       }
320       return 0;
321    },
322
323    _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) { return true; } return false; },
324    _blend: function(c1, c2) { var cc1 = OpenLayers.Rico.Color.createFromHex(c1); cc1.blend(OpenLayers.Rico.Color.createFromHex(c2)); return cc1; },
325    _background: function(el) { try { return OpenLayers.Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
326    _isTransparent: function() { return this.options.color == "transparent"; },
327    _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
328    _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
329    _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
330 };