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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.terminal.gwt.client;
  5. import java.util.HashSet;
  6. import java.util.Iterator;
  7. import java.util.Set;
  8. import com.google.gwt.user.client.DOM;
  9. import com.google.gwt.user.client.Element;
  10. import com.google.gwt.user.client.ui.HasWidgets;
  11. import com.google.gwt.user.client.ui.Widget;
  12. public class Util {
  13. /**
  14. * Helper method for debugging purposes.
  15. *
  16. * Stops execution on firefox browsers on a breakpoint.
  17. *
  18. */
  19. public static native void browserDebugger()
  20. /*-{
  21. if($wnd.console)
  22. debugger;
  23. }-*/;
  24. /**
  25. * Nulls oncontextmenu function on given element. We need to manually clear
  26. * context menu events due bad browsers memory leaks, since GWT don't
  27. * support them.
  28. *
  29. * @param el
  30. */
  31. public native static void removeContextMenuEvent(Element el)
  32. /*-{
  33. el.oncontextmenu = null;
  34. }-*/;
  35. /**
  36. * Called when the size of one or more widgets have changed during
  37. * rendering. Finds parent container and notifies them of the size change.
  38. *
  39. * @param widgets
  40. */
  41. public static void componentSizeUpdated(Set<Widget> widgets) {
  42. if (widgets.isEmpty()) {
  43. return;
  44. }
  45. Set<Container> parents = new HashSet<Container>();
  46. for (Widget widget : widgets) {
  47. Widget parent = widget.getParent();
  48. while (parent != null && !(parent instanceof Container)) {
  49. parent = parent.getParent();
  50. }
  51. if (parent != null) {
  52. parents.add((Container) parent);
  53. }
  54. }
  55. Set<Widget> parentChanges = new HashSet<Widget>();
  56. for (Container parent : parents) {
  57. if (!parent.childComponentSizesUpdated()) {
  58. parentChanges.add((Widget) parent);
  59. }
  60. }
  61. componentSizeUpdated(parentChanges);
  62. }
  63. /**
  64. * Traverses recursively ancestors until ContainerResizedListener child
  65. * widget is found. They will delegate it futher if needed.
  66. *
  67. * @param container
  68. */
  69. public static void runDescendentsLayout(HasWidgets container) {
  70. final Iterator childWidgets = container.iterator();
  71. while (childWidgets.hasNext()) {
  72. final Widget child = (Widget) childWidgets.next();
  73. if (child instanceof ContainerResizedListener) {
  74. int w = -1, h = -1;
  75. if (container instanceof WidgetSpaceAllocator) {
  76. w = ((WidgetSpaceAllocator) container)
  77. .getAllocatedWidth(child);
  78. h = ((WidgetSpaceAllocator) container)
  79. .getAllocatedHeight(child);
  80. }
  81. ((ContainerResizedListener) child).iLayout(w, h);
  82. } else if (child instanceof HasWidgets) {
  83. final HasWidgets childContainer = (HasWidgets) child;
  84. runDescendentsLayout(childContainer);
  85. }
  86. }
  87. }
  88. public interface WidgetSpaceAllocator {
  89. int getAllocatedWidth(Widget child);
  90. int getAllocatedHeight(Widget child);
  91. }
  92. /**
  93. * Returns closest parent Widget in hierarchy that implements Container
  94. * interface
  95. *
  96. * @param component
  97. * @return closest parent Container
  98. */
  99. public static Container getParentLayout(Widget component) {
  100. Widget parent = component.getParent();
  101. while (parent != null && !(parent instanceof Container)) {
  102. parent = parent.getParent();
  103. }
  104. if (parent != null && ((Container) parent).hasChildComponent(component)) {
  105. return (Container) parent;
  106. }
  107. return null;
  108. }
  109. /**
  110. * Detects if current browser is IE.
  111. *
  112. * @deprecated use BrowserInfo class instead
  113. *
  114. * @return true if IE
  115. */
  116. public static boolean isIE() {
  117. return BrowserInfo.get().isIE();
  118. }
  119. /**
  120. * Detects if current browser is IE6.
  121. *
  122. * @deprecated use BrowserInfo class instead
  123. *
  124. * @return true if IE6
  125. */
  126. public static boolean isIE6() {
  127. return BrowserInfo.get().isIE6();
  128. }
  129. /**
  130. * @deprecated use BrowserInfo class instead
  131. * @return
  132. */
  133. public static boolean isIE7() {
  134. return BrowserInfo.get().isIE7();
  135. }
  136. /**
  137. * @deprecated use BrowserInfo class instead
  138. * @return
  139. */
  140. public static boolean isFF2() {
  141. return BrowserInfo.get().isFF2();
  142. }
  143. private static final Element escapeHtmlHelper = DOM.createDiv();
  144. /**
  145. * Converts html entities to text.
  146. *
  147. * @param html
  148. * @return escaped string presentation of given html
  149. */
  150. public static String escapeHTML(String html) {
  151. DOM.setInnerText(escapeHtmlHelper, html);
  152. return DOM.getInnerHTML(escapeHtmlHelper);
  153. }
  154. /**
  155. * Adds transparent PNG fix to image element; only use for IE6.
  156. *
  157. * @param el
  158. * IMG element
  159. * @param blankImageUrl
  160. * URL to transparent one-pixel gif
  161. */
  162. public native static void addPngFix(Element el, String blankImageUrl)
  163. /*-{
  164. el.attachEvent("onload", function() {
  165. var src = el.src;
  166. if (src.indexOf(".png")<1) return;
  167. var w = el.width||16;
  168. var h = el.height||16;
  169. el.src =blankImageUrl;
  170. el.style.height = h+"px";
  171. el.style.width = w+"px";
  172. el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='crop');";
  173. },false);
  174. }-*/;
  175. /**
  176. * Clones given element as in JavaScript.
  177. *
  178. * Deprecate this if there appears similar method into GWT someday.
  179. *
  180. * @param element
  181. * @param deep
  182. * clone child tree also
  183. * @return
  184. */
  185. public static native Element cloneNode(Element element, boolean deep)
  186. /*-{
  187. return element.cloneNode(deep);
  188. }-*/;
  189. public static int measureHorizontalPadding(Element element, int paddingGuess) {
  190. String originalWidth = DOM.getStyleAttribute(element, "width");
  191. int originalOffsetWidth = element.getOffsetWidth();
  192. int widthGuess = (originalOffsetWidth + paddingGuess);
  193. DOM.setStyleAttribute(element, "width", widthGuess + "px");
  194. int padding = widthGuess - element.getOffsetWidth();
  195. DOM.setStyleAttribute(element, "width", originalWidth);
  196. return padding;
  197. }
  198. public static void setWidthExcludingPadding(Element element,
  199. int requestedWidth, int paddingGuess) {
  200. int widthGuess = requestedWidth - paddingGuess;
  201. if (widthGuess < 0) {
  202. widthGuess = 0;
  203. }
  204. DOM.setStyleAttribute(element, "width", widthGuess + "px");
  205. int captionOffsetWidth = DOM.getElementPropertyInt(element,
  206. "offsetWidth");
  207. int actualPadding = captionOffsetWidth - widthGuess;
  208. if (actualPadding != paddingGuess) {
  209. DOM.setStyleAttribute(element, "width", requestedWidth
  210. - actualPadding + "px");
  211. }
  212. }
  213. }