Corner.js 12 KB

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