3 * Copyright 2005 Sabre Airline Solutions
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 * file except in compliance with the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software distributed under the
11 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
12 * either express or implied. See the License for the specific language governing permissions
13 * and limitations under the License.
17 var Rico = new Object();
20 round: function(e, options) {
22 this._setOptions(options);
24 var color = this.options.color;
25 if ( this.options.color == "fromElement" )
26 color = this._background(e);
28 var bgColor = this.options.bgColor;
29 if ( this.options.bgColor == "fromParent" )
30 bgColor = this._background(e.offsetParent);
32 this._roundCornersImpl(e, color, bgColor);
35 /** This is a helper function to change the background
36 * color of <div> that has had Rico rounded corners added.
38 * It seems we cannot just set the background color for the
39 * outer <div> so each <span> element used to create the
40 * corners must have its background color set individually.
42 * @param {DOM} theDiv - A child of the outer <div> that was
43 * supplied to the `round` method.
45 * @param {str} newColor - The new background color to use.
47 changeColor: function(theDiv, newColor) {
49 theDiv.style.backgroundColor = newColor;
51 var spanElements = theDiv.parentNode.getElementsByTagName("span");
53 for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
54 spanElements[currIdx].style.backgroundColor = newColor;
59 /** This is a helper function to change the background
60 * opacity of <div> that has had Rico rounded corners added.
62 * See changeColor (above) for algorithm explanation
64 * @param {DOM} theDiv A child of the outer <div> that was
65 * supplied to the `round` method.
67 * @param {int} newOpacity The new opacity to use (0-1).
69 changeOpacity: function(theDiv, newOpacity) {
71 var mozillaOpacity = newOpacity;
72 var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';
74 theDiv.style.opacity = mozillaOpacity;
75 theDiv.style.filter = ieOpacity;
77 var spanElements = theDiv.parentNode.getElementsByTagName("span");
79 for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
80 spanElements[currIdx].style.opacity = mozillaOpacity;
81 spanElements[currIdx].style.filter = ieOpacity;
86 /** this function takes care of redoing the rico cornering
88 * you can't just call updateRicoCorners() again and pass it a
89 * new options string. you have to first remove the divs that
90 * rico puts on top and below the content div.
92 * @param {DOM} theDiv - A child of the outer <div> that was
93 * supplied to the `round` method.
95 * @param {Array} options - list of options
97 reRound: function(theDiv, options) {
99 var topRico = theDiv.parentNode.childNodes[0];
100 //theDiv would be theDiv.parentNode.childNodes[1]
101 var bottomRico = theDiv.parentNode.childNodes[2];
103 theDiv.parentNode.removeChild(topRico);
104 theDiv.parentNode.removeChild(bottomRico);
106 this.round(theDiv.parentNode, options);
109 _roundCornersImpl: function(e, color, bgColor) {
110 if(this.options.border)
111 this._renderBorder(e,bgColor);
112 if(this._isTopRounded())
113 this._roundTopCorners(e,color,bgColor);
114 if(this._isBottomRounded())
115 this._roundBottomCorners(e,color,bgColor);
118 _renderBorder: function(el,bgColor) {
119 var borderValue = "1px solid " + this._borderColor(bgColor);
120 var borderL = "border-left: " + borderValue;
121 var borderR = "border-right: " + borderValue;
122 var style = "style='" + borderL + ";" + borderR + "'";
123 el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
126 _roundTopCorners: function(el, color, bgColor) {
127 var corner = this._createCorner(bgColor);
128 for(var i=0 ; i < this.options.numSlices ; i++ )
129 corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
130 el.style.paddingTop = 0;
131 el.insertBefore(corner,el.firstChild);
134 _roundBottomCorners: function(el, color, bgColor) {
135 var corner = this._createCorner(bgColor);
136 for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
137 corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
138 el.style.paddingBottom = 0;
139 el.appendChild(corner);
142 _createCorner: function(bgColor) {
143 var corner = document.createElement("div");
144 corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
148 _createCornerSlice: function(color,bgColor, n, position) {
149 var slice = document.createElement("span");
151 var inStyle = slice.style;
152 inStyle.backgroundColor = color;
153 inStyle.display = "block";
154 inStyle.height = "1px";
155 inStyle.overflow = "hidden";
156 inStyle.fontSize = "1px";
158 var borderColor = this._borderColor(color,bgColor);
159 if ( this.options.border && n == 0 ) {
160 inStyle.borderTopStyle = "solid";
161 inStyle.borderTopWidth = "1px";
162 inStyle.borderLeftWidth = "0px";
163 inStyle.borderRightWidth = "0px";
164 inStyle.borderBottomWidth = "0px";
165 inStyle.height = "0px"; // assumes css compliant box model
166 inStyle.borderColor = borderColor;
168 else if(borderColor) {
169 inStyle.borderColor = borderColor;
170 inStyle.borderStyle = "solid";
171 inStyle.borderWidth = "0px 1px";
174 if ( !this.options.compact && (n == (this.options.numSlices-1)) )
175 inStyle.height = "2px";
177 this._setMargin(slice, n, position);
178 this._setBorder(slice, n, position);
182 _setOptions: function(options) {
185 color : "fromElement",
186 bgColor : "fromParent",
191 Object.extend(this.options, options || {});
193 this.options.numSlices = this.options.compact ? 2 : 4;
194 if ( this._isTransparent() )
195 this.options.blend = false;
198 _whichSideTop: function() {
199 if ( this._hasString(this.options.corners, "all", "top") )
202 if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
205 if (this.options.corners.indexOf("tl") >= 0)
207 else if (this.options.corners.indexOf("tr") >= 0)
212 _whichSideBottom: function() {
213 if ( this._hasString(this.options.corners, "all", "bottom") )
216 if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
219 if(this.options.corners.indexOf("bl") >=0)
221 else if(this.options.corners.indexOf("br")>=0)
226 _borderColor : function(color,bgColor) {
227 if ( color == "transparent" )
229 else if ( this.options.border )
230 return this.options.border;
231 else if ( this.options.blend )
232 return this._blend( bgColor, color );
238 _setMargin: function(el, n, corners) {
239 var marginSize = this._marginSize(n);
240 var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
242 if ( whichSide == "left" ) {
243 el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
245 else if ( whichSide == "right" ) {
246 el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px";
249 el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
253 _setBorder: function(el,n,corners) {
254 var borderSize = this._borderSize(n);
255 var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
256 if ( whichSide == "left" ) {
257 el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
259 else if ( whichSide == "right" ) {
260 el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px";
263 el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
265 if (this.options.border != false)
266 el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
269 _marginSize: function(n) {
270 if ( this._isTransparent() )
273 var marginSizes = [ 5, 3, 2, 1 ];
274 var blendedMarginSizes = [ 3, 2, 1, 0 ];
275 var compactMarginSizes = [ 2, 1 ];
276 var smBlendedMarginSizes = [ 1, 0 ];
278 if ( this.options.compact && this.options.blend )
279 return smBlendedMarginSizes[n];
280 else if ( this.options.compact )
281 return compactMarginSizes[n];
282 else if ( this.options.blend )
283 return blendedMarginSizes[n];
285 return marginSizes[n];
288 _borderSize: function(n) {
289 var transparentBorderSizes = [ 5, 3, 2, 1 ];
290 var blendedBorderSizes = [ 2, 1, 1, 1 ];
291 var compactBorderSizes = [ 1, 0 ];
292 var actualBorderSizes = [ 0, 2, 0, 0 ];
294 if ( this.options.compact && (this.options.blend || this._isTransparent()) )
296 else if ( this.options.compact )
297 return compactBorderSizes[n];
298 else if ( this.options.blend )
299 return blendedBorderSizes[n];
300 else if ( this.options.border )
301 return actualBorderSizes[n];
302 else if ( this._isTransparent() )
303 return transparentBorderSizes[n];
307 _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
308 _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
309 _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
310 _isTransparent: function() { return this.options.color == "transparent"; },
311 _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
312 _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
313 _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }