You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ComputedStyle.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client;
  17. import com.google.gwt.core.client.JavaScriptObject;
  18. import com.google.gwt.dom.client.Element;
  19. public class ComputedStyle {
  20. protected final JavaScriptObject computedStyle;
  21. private final Element elem;
  22. /**
  23. * Gets this element's computed style object which can be used to gather
  24. * information about the current state of the rendered node.
  25. * <p>
  26. * Note that this method is expensive. Wherever possible, reuse the returned
  27. * object.
  28. *
  29. * @param elem
  30. * the element
  31. * @return the computed style
  32. */
  33. public ComputedStyle(Element elem) {
  34. computedStyle = getComputedStyle(elem);
  35. this.elem = elem;
  36. }
  37. private static native JavaScriptObject getComputedStyle(Element elem)
  38. /*-{
  39. if(elem.nodeType != 1) {
  40. return {};
  41. }
  42. if($wnd.document.defaultView && $wnd.document.defaultView.getComputedStyle) {
  43. return $wnd.document.defaultView.getComputedStyle(elem, null);
  44. }
  45. if(elem.currentStyle) {
  46. return elem.currentStyle;
  47. }
  48. }-*/;
  49. /**
  50. *
  51. * @param name
  52. * name of the CSS property in camelCase
  53. * @return the value of the property, normalized for across browsers (each
  54. * browser returns pixel values whenever possible).
  55. */
  56. public final native String getProperty(String name)
  57. /*-{
  58. var cs = this.@com.vaadin.client.ComputedStyle::computedStyle;
  59. var elem = this.@com.vaadin.client.ComputedStyle::elem;
  60. // Border values need to be checked separately. The width might have a
  61. // meaningful value even if the border style is "none". In that case the
  62. // value should be 0.
  63. if(name.indexOf("border") > -1 && name.indexOf("Width") > -1) {
  64. var borderStyleProp = name.substring(0,name.length-5) + "Style";
  65. if(cs.getPropertyValue)
  66. var borderStyle = cs.getPropertyValue(borderStyleProp);
  67. else // IE
  68. var borderStyle = cs[borderStyleProp];
  69. if(borderStyle == "none")
  70. return "0px";
  71. }
  72. if(cs.getPropertyValue) {
  73. // Convert name to dashed format
  74. name = name.replace(/([A-Z])/g, "-$1").toLowerCase();
  75. var ret = cs.getPropertyValue(name);
  76. } else {
  77. var ret = cs[name];
  78. var style = elem.style;
  79. // From the awesome hack by Dean Edwards
  80. // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  81. // If we're not dealing with a regular pixel number
  82. // but a number that has a weird ending, we need to convert it to pixels
  83. if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
  84. // Remember the original values
  85. var left = style.left, rsLeft = elem.runtimeStyle.left;
  86. // Put in the new values to get a computed value out
  87. elem.runtimeStyle.left = cs.left;
  88. style.left = ret || 0;
  89. ret = style.pixelLeft + "px";
  90. // Revert the changed values
  91. style.left = left;
  92. elem.runtimeStyle.left = rsLeft;
  93. }
  94. }
  95. // Normalize margin values. This is not totally valid, but in most cases
  96. // it is what the user wants to know.
  97. if(name.indexOf("margin") > -1 && ret == "auto") {
  98. return "0px";
  99. }
  100. // Some browsers return undefined width and height values as "auto", so
  101. // we need to retrieve those ourselves.
  102. if (name == "width" && ret == "auto") {
  103. ret = elem.clientWidth + "px";
  104. } else if (name == "height" && ret == "auto") {
  105. ret = elem.clientHeight + "px";
  106. }
  107. return ret;
  108. }-*/;
  109. /**
  110. * Retrieves the given computed property as an integer
  111. *
  112. * Returns 0 if the property cannot be converted to an integer
  113. *
  114. * @param name
  115. * the property to retrieve
  116. * @return the integer value of the property or 0
  117. */
  118. public final int getIntProperty(String name) {
  119. Profiler.enter("ComputedStyle.getIntProperty");
  120. String value = getProperty(name);
  121. int result = parseIntNative(value);
  122. Profiler.leave("ComputedStyle.getIntProperty");
  123. return result;
  124. }
  125. /**
  126. * Retrieves the given computed property as a double
  127. *
  128. * Returns NaN if the property cannot be converted to a double
  129. *
  130. * @param name
  131. * the property to retrieve
  132. * @return the double value of the property
  133. */
  134. public final double getDoubleProperty(String name) {
  135. Profiler.enter("ComputedStyle.getDoubleProperty");
  136. String value = getProperty(name);
  137. double result = parseDoubleNative(value);
  138. Profiler.leave("ComputedStyle.getDoubleProperty");
  139. return result;
  140. }
  141. /**
  142. * Get current margin values from the DOM. The array order is the default
  143. * CSS order: top, right, bottom, left.
  144. */
  145. public final int[] getMargin() {
  146. int[] margin = { 0, 0, 0, 0 };
  147. margin[0] = getIntProperty("marginTop");
  148. margin[1] = getIntProperty("marginRight");
  149. margin[2] = getIntProperty("marginBottom");
  150. margin[3] = getIntProperty("marginLeft");
  151. return margin;
  152. }
  153. /**
  154. * Get current padding values from the DOM. The array order is the default
  155. * CSS order: top, right, bottom, left.
  156. */
  157. public final int[] getPadding() {
  158. int[] padding = { 0, 0, 0, 0 };
  159. padding[0] = getIntProperty("paddingTop");
  160. padding[1] = getIntProperty("paddingRight");
  161. padding[2] = getIntProperty("paddingBottom");
  162. padding[3] = getIntProperty("paddingLeft");
  163. return padding;
  164. }
  165. /**
  166. * Get current border values from the DOM. The array order is the default
  167. * CSS order: top, right, bottom, left.
  168. */
  169. public final int[] getBorder() {
  170. int[] border = { 0, 0, 0, 0 };
  171. border[0] = getIntProperty("borderTopWidth");
  172. border[1] = getIntProperty("borderRightWidth");
  173. border[2] = getIntProperty("borderBottomWidth");
  174. border[3] = getIntProperty("borderLeftWidth");
  175. return border;
  176. }
  177. /**
  178. * Returns the current width from the DOM.
  179. *
  180. * @since 7.5.1
  181. * @return the computed width
  182. */
  183. public double getWidth() {
  184. return getDoubleProperty("width");
  185. }
  186. /**
  187. * Returns the current height from the DOM.
  188. *
  189. * @since 7.5.1
  190. * @return the computed height
  191. */
  192. public double getHeight() {
  193. return getDoubleProperty("height");
  194. }
  195. /**
  196. * Takes a String value e.g. "12px" and parses that to Integer 12.
  197. *
  198. * @param String
  199. * a value starting with a number
  200. * @return Integer the value from the string before any non-numeric
  201. * characters. If the value cannot be parsed to a number, returns
  202. * <code>null</code>.
  203. *
  204. * @deprecated Since 7.1.4, the method {@link #parseIntNative(String)} is
  205. * used internally and this method does not belong in the public
  206. * API of {@link ComputedStyle}. {@link #parseInt(String)} might
  207. * be removed or moved to a utility class in future versions.
  208. */
  209. @Deprecated
  210. public static native Integer parseInt(final String value)
  211. /*-{
  212. var number = parseInt(value, 10);
  213. if (isNaN(number))
  214. return null;
  215. else
  216. // $entry not needed as function is not exported
  217. return @java.lang.Integer::valueOf(I)(number);
  218. }-*/;
  219. /**
  220. * Takes a String value e.g. "12px" and parses that to int 12.
  221. *
  222. * <p>
  223. * This method returns 0 for <code>NaN</code>.
  224. *
  225. * @param String
  226. * a value starting with a number
  227. * @return int the value from the string before any non-numeric characters.
  228. * If the value cannot be parsed to a number, returns 0.
  229. */
  230. private static native int parseIntNative(final String value)
  231. /*-{
  232. var number = parseInt(value, 10);
  233. if (isNaN(number))
  234. return 0;
  235. else
  236. return number;
  237. }-*/;
  238. /**
  239. * Takes a String value e.g. "12.3px" and parses that to a double, 12.3.
  240. *
  241. * @param String
  242. * a value starting with a number
  243. * @return the value from the string before any non-numeric characters or
  244. * NaN if the value cannot be parsed as a number
  245. */
  246. private static native double parseDoubleNative(final String value)
  247. /*-{
  248. return parseFloat(value);
  249. }-*/;
  250. /**
  251. * Returns the sum of the top and bottom border width
  252. *
  253. * @since 7.5.3
  254. * @return the sum of the top and bottom border
  255. */
  256. public double getBorderHeight() {
  257. double borderHeight = getDoubleProperty("borderTopWidth");
  258. borderHeight += getDoubleProperty("borderBottomWidth");
  259. return borderHeight;
  260. }
  261. /**
  262. * Returns the sum of the left and right border width
  263. *
  264. * @since 7.5.3
  265. * @return the sum of the left and right border
  266. */
  267. public double getBorderWidth() {
  268. double borderWidth = getDoubleProperty("borderLeftWidth");
  269. borderWidth += getDoubleProperty("borderRightWidth");
  270. return borderWidth;
  271. }
  272. /**
  273. * Returns the sum of the top and bottom padding
  274. *
  275. * @since 7.5.3
  276. * @return the sum of the top and bottom padding
  277. */
  278. public double getPaddingHeight() {
  279. double paddingHeight = getDoubleProperty("paddingTop");
  280. paddingHeight += getDoubleProperty("paddingBottom");
  281. return paddingHeight;
  282. }
  283. /**
  284. * Returns the sum of the top and bottom padding
  285. *
  286. * @since 7.5.3
  287. * @return the sum of the left and right padding
  288. */
  289. public double getPaddingWidth() {
  290. double paddingWidth = getDoubleProperty("paddingLeft");
  291. paddingWidth += getDoubleProperty("paddingRight");
  292. return paddingWidth;
  293. }
  294. }