2 * This file has been edited substantially from the Rico-released
3 * version by the OpenLayers development team.
5 * Copyright 2005 Sabre Airline Solutions
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 OpenLayers.Rico = new Object();
21 OpenLayers.Rico.Corner = {
23 round: function(e, options) {
24 e = OpenLayers.Util.getElement(e);
25 this._setOptions(options);
27 var color = this.options.color;
28 if ( this.options.color == "fromElement" ) {
29 color = this._background(e);
31 var bgColor = this.options.bgColor;
32 if ( this.options.bgColor == "fromParent" ) {
33 bgColor = this._background(e.offsetParent);
35 this._roundCornersImpl(e, color, bgColor);
38 /** This is a helper function to change the background
39 * color of <div> that has had Rico rounded corners added.
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.
45 * @param {DOM} theDiv - A child of the outer <div> that was
46 * supplied to the `round` method.
48 * @param {String} newColor - The new background color to use.
50 changeColor: function(theDiv, newColor) {
52 theDiv.style.backgroundColor = newColor;
54 var spanElements = theDiv.parentNode.getElementsByTagName("span");
56 for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
57 spanElements[currIdx].style.backgroundColor = newColor;
62 /** This is a helper function to change the background
63 * opacity of <div> that has had Rico rounded corners added.
65 * See changeColor (above) for algorithm explanation
67 * @param {DOM} theDiv A child of the outer <div> that was
68 * supplied to the `round` method.
70 * @param {int} newOpacity The new opacity to use (0-1).
72 changeOpacity: function(theDiv, newOpacity) {
74 var mozillaOpacity = newOpacity;
75 var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';
77 theDiv.style.opacity = mozillaOpacity;
78 theDiv.style.filter = ieOpacity;
80 var spanElements = theDiv.parentNode.getElementsByTagName("span");
82 for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
83 spanElements[currIdx].style.opacity = mozillaOpacity;
84 spanElements[currIdx].style.filter = ieOpacity;
89 /** this function takes care of redoing the rico cornering
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.
95 * @param {DOM} theDiv - A child of the outer <div> that was
96 * supplied to the `round` method.
98 * @param {Object} options - list of options
100 reRound: function(theDiv, options) {
102 var topRico = theDiv.parentNode.childNodes[0];
103 //theDiv would be theDiv.parentNode.childNodes[1]
104 var bottomRico = theDiv.parentNode.childNodes[2];
106 theDiv.parentNode.removeChild(topRico);
107 theDiv.parentNode.removeChild(bottomRico);
109 this.round(theDiv.parentNode, options);
112 _roundCornersImpl: function(e, color, bgColor) {
113 if(this.options.border) {
114 this._renderBorder(e,bgColor);
116 if(this._isTopRounded()) {
117 this._roundTopCorners(e,color,bgColor);
119 if(this._isBottomRounded()) {
120 this._roundBottomCorners(e,color,bgColor);
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>";
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"));
137 el.style.paddingTop = 0;
138 el.insertBefore(corner,el.firstChild);
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"));
146 el.style.paddingBottom = 0;
147 el.appendChild(corner);
150 _createCorner: function(bgColor) {
151 var corner = document.createElement("div");
152 corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
156 _createCornerSlice: function(color,bgColor, n, position) {
157 var slice = document.createElement("span");
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";
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;
176 else if(borderColor) {
177 inStyle.borderColor = borderColor;
178 inStyle.borderStyle = "solid";
179 inStyle.borderWidth = "0px 1px";
182 if ( !this.options.compact && (n == (this.options.numSlices-1)) ) {
183 inStyle.height = "2px";
185 this._setMargin(slice, n, position);
186 this._setBorder(slice, n, position);
190 _setOptions: function(options) {
193 color : "fromElement",
194 bgColor : "fromParent",
199 OpenLayers.Util.extend(this.options, options || {});
201 this.options.numSlices = this.options.compact ? 2 : 4;
202 if ( this._isTransparent() ) {
203 this.options.blend = false;
207 _whichSideTop: function() {
208 if ( this._hasString(this.options.corners, "all", "top") ) {
211 if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 ) {
214 if (this.options.corners.indexOf("tl") >= 0) {
216 } else if (this.options.corners.indexOf("tr") >= 0) {
222 _whichSideBottom: function() {
223 if ( this._hasString(this.options.corners, "all", "bottom") ) {
226 if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 ) {
230 if(this.options.corners.indexOf("bl") >=0) {
232 } else if(this.options.corners.indexOf("br")>=0) {
238 _borderColor : function(color,bgColor) {
239 if ( color == "transparent" ) {
241 } else if ( this.options.border ) {
242 return this.options.border;
243 } else if ( this.options.blend ) {
244 return this._blend( bgColor, color );
251 _setMargin: function(el, n, corners) {
252 var marginSize = this._marginSize(n);
253 var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
255 if ( whichSide == "left" ) {
256 el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
258 else if ( whichSide == "right" ) {
259 el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px";
262 el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
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";
272 else if ( whichSide == "right" ) {
273 el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px";
276 el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
278 if (this.options.border != false) {
279 el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
283 _marginSize: function(n) {
284 if ( this._isTransparent() ) {
287 var marginSizes = [ 5, 3, 2, 1 ];
288 var blendedMarginSizes = [ 3, 2, 1, 0 ];
289 var compactMarginSizes = [ 2, 1 ];
290 var smBlendedMarginSizes = [ 1, 0 ];
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];
299 return marginSizes[n];
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 ];
309 if ( this.options.compact && (this.options.blend || this._isTransparent()) ) {
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];
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; }