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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * Copyright 2000-2016 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. * @since 7.5.1
  131. * @param name
  132. * the property to retrieve
  133. * @return the double value of the property
  134. */
  135. public final double getDoubleProperty(String name) {
  136. Profiler.enter("ComputedStyle.getDoubleProperty");
  137. String value = getProperty(name);
  138. double result = parseDoubleNative(value);
  139. Profiler.leave("ComputedStyle.getDoubleProperty");
  140. return result;
  141. }
  142. /**
  143. * Get current margin values from the DOM. The array order is the default
  144. * CSS order: top, right, bottom, left.
  145. */
  146. public final int[] getMargin() {
  147. int[] margin = { 0, 0, 0, 0 };
  148. margin[0] = getIntProperty("marginTop");
  149. margin[1] = getIntProperty("marginRight");
  150. margin[2] = getIntProperty("marginBottom");
  151. margin[3] = getIntProperty("marginLeft");
  152. return margin;
  153. }
  154. /**
  155. * Get current padding values from the DOM. The array order is the default
  156. * CSS order: top, right, bottom, left.
  157. */
  158. public final int[] getPadding() {
  159. int[] padding = { 0, 0, 0, 0 };
  160. padding[0] = getIntProperty("paddingTop");
  161. padding[1] = getIntProperty("paddingRight");
  162. padding[2] = getIntProperty("paddingBottom");
  163. padding[3] = getIntProperty("paddingLeft");
  164. return padding;
  165. }
  166. /**
  167. * Get current border values from the DOM. The array order is the default
  168. * CSS order: top, right, bottom, left.
  169. */
  170. public final int[] getBorder() {
  171. int[] border = { 0, 0, 0, 0 };
  172. border[0] = getIntProperty("borderTopWidth");
  173. border[1] = getIntProperty("borderRightWidth");
  174. border[2] = getIntProperty("borderBottomWidth");
  175. border[3] = getIntProperty("borderLeftWidth");
  176. return border;
  177. }
  178. /**
  179. * Returns the current width from the DOM.
  180. *
  181. * @since 7.5.1
  182. * @return the computed width
  183. */
  184. public double getWidth() {
  185. return getDoubleProperty("width");
  186. }
  187. /**
  188. * Returns the current height from the DOM.
  189. *
  190. * @since 7.5.1
  191. * @return the computed height
  192. */
  193. public double getHeight() {
  194. return getDoubleProperty("height");
  195. }
  196. /**
  197. * Takes a String value e.g. "12px" and parses that to Integer 12.
  198. *
  199. * @param String
  200. * a value starting with a number
  201. * @return Integer the value from the string before any non-numeric
  202. * characters. If the value cannot be parsed to a number, returns
  203. * <code>null</code>.
  204. *
  205. * @deprecated Since 7.1.4, the method {@link #parseIntNative(String)} is
  206. * used internally and this method does not belong in the public
  207. * API of {@link ComputedStyle}. {@link #parseInt(String)} might
  208. * be removed or moved to a utility class in future versions.
  209. */
  210. @Deprecated
  211. public static native Integer parseInt(final String value)
  212. /*-{
  213. var number = parseInt(value, 10);
  214. if (isNaN(number))
  215. return null;
  216. else
  217. // $entry not needed as function is not exported
  218. return @java.lang.Integer::valueOf(I)(number);
  219. }-*/;
  220. /**
  221. * Takes a String value e.g. "12px" and parses that to int 12.
  222. *
  223. * <p>
  224. * This method returns 0 for <code>NaN</code>.
  225. *
  226. * @param String
  227. * a value starting with a number
  228. * @return int the value from the string before any non-numeric characters.
  229. * If the value cannot be parsed to a number, returns 0.
  230. */
  231. private static native int parseIntNative(final String value)
  232. /*-{
  233. var number = parseInt(value, 10);
  234. if (isNaN(number))
  235. return 0;
  236. else
  237. return number;
  238. }-*/;
  239. /**
  240. * Takes a String value e.g. "12.3px" and parses that to a double, 12.3.
  241. *
  242. * @param String
  243. * a value starting with a number
  244. * @return the value from the string before any non-numeric characters or
  245. * NaN if the value cannot be parsed as a number
  246. */
  247. private static native double parseDoubleNative(final String value)
  248. /*-{
  249. return parseFloat(value);
  250. }-*/;
  251. /**
  252. * Returns the sum of the top and bottom border width
  253. *
  254. * @since 7.5.3
  255. * @return the sum of the top and bottom border
  256. */
  257. public double getBorderHeight() {
  258. double borderHeight = getDoubleProperty("borderTopWidth");
  259. borderHeight += getDoubleProperty("borderBottomWidth");
  260. return borderHeight;
  261. }
  262. /**
  263. * Returns the sum of the left and right border width
  264. *
  265. * @since 7.5.3
  266. * @return the sum of the left and right border
  267. */
  268. public double getBorderWidth() {
  269. double borderWidth = getDoubleProperty("borderLeftWidth");
  270. borderWidth += getDoubleProperty("borderRightWidth");
  271. return borderWidth;
  272. }
  273. /**
  274. * Returns the sum of the top and bottom padding
  275. *
  276. * @since 7.5.3
  277. * @return the sum of the top and bottom padding
  278. */
  279. public double getPaddingHeight() {
  280. double paddingHeight = getDoubleProperty("paddingTop");
  281. paddingHeight += getDoubleProperty("paddingBottom");
  282. return paddingHeight;
  283. }
  284. /**
  285. * Returns the sum of the top and bottom padding
  286. *
  287. * @since 7.5.3
  288. * @return the sum of the left and right padding
  289. */
  290. public double getPaddingWidth() {
  291. double paddingWidth = getDoubleProperty("paddingLeft");
  292. paddingWidth += getDoubleProperty("paddingRight");
  293. return paddingWidth;
  294. }
  295. /**
  296. * Returns the sum of the top and bottom margin
  297. *
  298. * @since 7.5.6
  299. * @return the sum of the top and bottom margin
  300. */
  301. public double getMarginHeight() {
  302. double marginHeight = getDoubleProperty("marginTop");
  303. marginHeight += getDoubleProperty("marginBottom");
  304. return marginHeight;
  305. }
  306. /**
  307. * Returns the sum of the top and bottom margin
  308. *
  309. * @since 7.5.6
  310. * @return the sum of the left and right margin
  311. */
  312. public double getMarginWidth() {
  313. double marginWidth = getDoubleProperty("marginLeft");
  314. marginWidth += getDoubleProperty("marginRight");
  315. return marginWidth;
  316. }
  317. }