Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

VDebugConsole.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client;
  5. import java.util.List;
  6. import java.util.Set;
  7. import com.google.gwt.core.client.JsArray;
  8. import com.google.gwt.event.dom.client.ClickEvent;
  9. import com.google.gwt.event.dom.client.ClickHandler;
  10. import com.google.gwt.user.client.DOM;
  11. import com.google.gwt.user.client.Element;
  12. import com.google.gwt.user.client.Event;
  13. import com.google.gwt.user.client.EventPreview;
  14. import com.google.gwt.user.client.Window;
  15. import com.google.gwt.user.client.Window.Location;
  16. import com.google.gwt.user.client.ui.Button;
  17. import com.google.gwt.user.client.ui.CheckBox;
  18. import com.google.gwt.user.client.ui.FlowPanel;
  19. import com.google.gwt.user.client.ui.HTML;
  20. import com.google.gwt.user.client.ui.HorizontalPanel;
  21. import com.google.gwt.user.client.ui.Label;
  22. import com.google.gwt.user.client.ui.Panel;
  23. import com.google.gwt.user.client.ui.Tree;
  24. import com.google.gwt.user.client.ui.TreeItem;
  25. import com.google.gwt.user.client.ui.VerticalPanel;
  26. import com.google.gwt.user.client.ui.Widget;
  27. import com.vaadin.terminal.gwt.client.ui.VOverlay;
  28. public final class VDebugConsole extends VOverlay implements Console {
  29. /**
  30. * Builds number. For example 0-custom_tag in 5.0.0-custom_tag.
  31. */
  32. public static final String VERSION;
  33. /* Initialize version numbers from string replaced by build-script. */
  34. static {
  35. if ("@VERSION@".equals("@" + "VERSION" + "@")) {
  36. VERSION = "5.9.9-INTERNAL-NONVERSIONED-DEBUG-BUILD";
  37. } else {
  38. VERSION = "@VERSION@";
  39. }
  40. }
  41. Element caption = DOM.createDiv();
  42. private Panel panel;
  43. private Button clear = new Button("Clear console");
  44. private Button restart = new Button("Restart app");
  45. private Button forceLayout = new Button("Force layout");
  46. private Button analyzeLayout = new Button("Analyze layouts");
  47. private HorizontalPanel actions;
  48. private boolean collapsed = false;
  49. private boolean resizing;
  50. private int startX;
  51. private int startY;
  52. private int initialW;
  53. private int initialH;
  54. private boolean moving = false;
  55. private int origTop;
  56. private int origLeft;
  57. private ApplicationConnection client;
  58. private ApplicationConfiguration conf;
  59. private static final String help = "Drag=move, shift-drag=resize, doubleclick=min/max."
  60. + "Use debug=quiet to log only to browser console.";
  61. public VDebugConsole(ApplicationConnection client,
  62. ApplicationConfiguration cnf, boolean showWindow) {
  63. super(false, false);
  64. this.client = client;
  65. conf = cnf;
  66. panel = new FlowPanel();
  67. if (showWindow) {
  68. DOM.appendChild(getContainerElement(), caption);
  69. setWidget(panel);
  70. caption.setClassName("v-debug-console-caption");
  71. setStyleName("v-debug-console");
  72. DOM.setStyleAttribute(getElement(), "zIndex", 20000 + "");
  73. DOM.setStyleAttribute(getElement(), "overflow", "hidden");
  74. sinkEvents(Event.ONDBLCLICK);
  75. sinkEvents(Event.MOUSEEVENTS);
  76. panel.setStyleName("v-debug-console-content");
  77. caption.setInnerHTML("Debug window");
  78. caption.setTitle(help);
  79. show();
  80. minimize();
  81. actions = new HorizontalPanel();
  82. actions.add(clear);
  83. actions.add(restart);
  84. actions.add(forceLayout);
  85. actions.add(analyzeLayout);
  86. panel.add(actions);
  87. panel.add(new HTML("<i>" + help + "</i>"));
  88. clear.addClickHandler(new ClickHandler() {
  89. public void onClick(ClickEvent event) {
  90. int width = panel.getOffsetWidth();
  91. int height = panel.getOffsetHeight();
  92. panel = new FlowPanel();
  93. panel.setPixelSize(width, height);
  94. panel.setStyleName("v-debug-console-content");
  95. panel.add(actions);
  96. setWidget(panel);
  97. }
  98. });
  99. restart.addClickHandler(new ClickHandler() {
  100. public void onClick(ClickEvent event) {
  101. String queryString = Window.Location.getQueryString();
  102. if (queryString != null
  103. && queryString.contains("restartApplications")) {
  104. Window.Location.reload();
  105. } else {
  106. String url = Location.getHref();
  107. String separator = "?";
  108. if (url.contains("?")) {
  109. separator = "&";
  110. }
  111. if (!url.contains("restartApplication")) {
  112. url += separator;
  113. url += "restartApplication";
  114. }
  115. if (!"".equals(Location.getHash())) {
  116. String hash = Location.getHash();
  117. url = url.replace(hash, "") + hash;
  118. }
  119. Window.Location.replace(url);
  120. }
  121. }
  122. });
  123. forceLayout.addClickHandler(new ClickHandler() {
  124. public void onClick(ClickEvent event) {
  125. VDebugConsole.this.client.forceLayout();
  126. }
  127. });
  128. analyzeLayout.addClickHandler(new ClickHandler() {
  129. public void onClick(ClickEvent event) {
  130. List<ApplicationConnection> runningApplications = ApplicationConfiguration
  131. .getRunningApplications();
  132. for (ApplicationConnection applicationConnection : runningApplications) {
  133. applicationConnection.analyzeLayouts();
  134. }
  135. }
  136. });
  137. analyzeLayout
  138. .setTitle("Analyzes currently rendered view and "
  139. + "reports possible common problems in usage of relative sizes."
  140. + "Will cause server visit/rendering of whole screen + lose of"
  141. + " all non committed variables form client side.");
  142. }
  143. log("Vaadin application servlet version: " + cnf.getServletVersion());
  144. log("Widget set is built on version: " + VERSION);
  145. log("Application version: " + cnf.getApplicationVersion());
  146. if (!cnf.getServletVersion().equals(VERSION)) {
  147. error("Warning: your widget set seems to be built with a different "
  148. + "version than the one used on server. Unexpected "
  149. + "behavior may occur.");
  150. }
  151. }
  152. private EventPreview dragpreview = new EventPreview() {
  153. public boolean onEventPreview(Event event) {
  154. onBrowserEvent(event);
  155. return false;
  156. }
  157. };
  158. @Override
  159. public void onBrowserEvent(Event event) {
  160. super.onBrowserEvent(event);
  161. switch (DOM.eventGetType(event)) {
  162. case Event.ONMOUSEDOWN:
  163. if (DOM.eventGetShiftKey(event)) {
  164. resizing = true;
  165. DOM.setCapture(getElement());
  166. startX = DOM.eventGetScreenX(event);
  167. startY = DOM.eventGetScreenY(event);
  168. initialW = VDebugConsole.this.getOffsetWidth();
  169. initialH = VDebugConsole.this.getOffsetHeight();
  170. DOM.eventCancelBubble(event, true);
  171. DOM.eventPreventDefault(event);
  172. DOM.addEventPreview(dragpreview);
  173. } else if (DOM.eventGetTarget(event) == caption) {
  174. moving = true;
  175. startX = DOM.eventGetScreenX(event);
  176. startY = DOM.eventGetScreenY(event);
  177. origTop = getAbsoluteTop();
  178. origLeft = getAbsoluteLeft();
  179. DOM.eventCancelBubble(event, true);
  180. DOM.eventPreventDefault(event);
  181. DOM.addEventPreview(dragpreview);
  182. }
  183. break;
  184. case Event.ONMOUSEMOVE:
  185. if (resizing) {
  186. int deltaX = startX - DOM.eventGetScreenX(event);
  187. int detalY = startY - DOM.eventGetScreenY(event);
  188. int w = initialW - deltaX;
  189. if (w < 30) {
  190. w = 30;
  191. }
  192. int h = initialH - detalY;
  193. if (h < 40) {
  194. h = 40;
  195. }
  196. VDebugConsole.this.setPixelSize(w, h);
  197. DOM.eventCancelBubble(event, true);
  198. DOM.eventPreventDefault(event);
  199. } else if (moving) {
  200. int deltaX = startX - DOM.eventGetScreenX(event);
  201. int detalY = startY - DOM.eventGetScreenY(event);
  202. int left = origLeft - deltaX;
  203. if (left < 0) {
  204. left = 0;
  205. }
  206. int top = origTop - detalY;
  207. if (top < 0) {
  208. top = 0;
  209. }
  210. VDebugConsole.this.setPopupPosition(left, top);
  211. DOM.eventCancelBubble(event, true);
  212. DOM.eventPreventDefault(event);
  213. }
  214. break;
  215. case Event.ONLOSECAPTURE:
  216. case Event.ONMOUSEUP:
  217. if (resizing) {
  218. DOM.releaseCapture(getElement());
  219. resizing = false;
  220. } else if (moving) {
  221. DOM.releaseCapture(getElement());
  222. moving = false;
  223. }
  224. DOM.removeEventPreview(dragpreview);
  225. break;
  226. case Event.ONDBLCLICK:
  227. if (DOM.eventGetTarget(event) == caption) {
  228. if (collapsed) {
  229. panel.setVisible(true);
  230. setPixelSize(220, 300);
  231. } else {
  232. panel.setVisible(false);
  233. setPixelSize(120, 20);
  234. }
  235. collapsed = !collapsed;
  236. }
  237. break;
  238. default:
  239. break;
  240. }
  241. }
  242. private void minimize() {
  243. setPixelSize(400, 150);
  244. setPopupPosition(Window.getClientWidth() - 410, Window
  245. .getClientHeight() - 160);
  246. }
  247. @Override
  248. public void setPixelSize(int width, int height) {
  249. panel.setHeight((height - 20) + "px");
  250. panel.setWidth((width - 2) + "px");
  251. }
  252. /*
  253. * (non-Javadoc)
  254. *
  255. * @see com.vaadin.terminal.gwt.client.Console#log(java.lang.String)
  256. */
  257. public void log(String msg) {
  258. panel.add(new HTML(msg));
  259. System.out.println(msg);
  260. consoleLog(msg);
  261. }
  262. /*
  263. * (non-Javadoc)
  264. *
  265. * @see com.vaadin.terminal.gwt.client.Console#error(java.lang.String)
  266. */
  267. public void error(String msg) {
  268. panel.add((new HTML(msg)));
  269. System.err.println(msg);
  270. consoleErr(msg);
  271. }
  272. /*
  273. * (non-Javadoc)
  274. *
  275. * @see com.vaadin.terminal.gwt.client.Console#printObject(java.lang.
  276. * Object)
  277. */
  278. public void printObject(Object msg) {
  279. panel.add((new Label(msg.toString())));
  280. consoleLog(msg.toString());
  281. }
  282. /*
  283. * (non-Javadoc)
  284. *
  285. * @see com.vaadin.terminal.gwt.client.Console#dirUIDL(com.vaadin
  286. * .terminal.gwt.client.UIDL)
  287. */
  288. public void dirUIDL(UIDL u) {
  289. if (panel.isAttached()) {
  290. panel.add(new VUIDLBrowser(u, conf));
  291. }
  292. consoleDir(u);
  293. // consoleLog(u.getChildrenAsXML());
  294. }
  295. private static native void consoleDir(UIDL u)
  296. /*-{
  297. if($wnd.console && $wnd.console.log) {
  298. if($wnd.console.dir) {
  299. $wnd.console.dir(u);
  300. } else {
  301. $wnd.console.log(u);
  302. }
  303. }
  304. }-*/;
  305. private static native void consoleLog(String msg)
  306. /*-{
  307. if($wnd.console && $wnd.console.log) {
  308. $wnd.console.log(msg);
  309. }
  310. }-*/;
  311. private static native void consoleErr(String msg)
  312. /*-{
  313. if($wnd.console) {
  314. if ($wnd.console.error)
  315. $wnd.console.error(msg);
  316. else if ($wnd.console.log)
  317. $wnd.console.log(msg);
  318. }
  319. }-*/;
  320. public void printLayoutProblems(ValueMap meta, ApplicationConnection ac,
  321. Set<Paintable> zeroHeightComponents,
  322. Set<Paintable> zeroWidthComponents) {
  323. JsArray<ValueMap> valueMapArray = meta
  324. .getJSValueMapArray("invalidLayouts");
  325. int size = valueMapArray.length();
  326. panel.add(new HTML("<div>************************</di>"
  327. + "<h4>Layouts analyzed on server, total top level problems: "
  328. + size + " </h4>"));
  329. if (size > 0) {
  330. Tree tree = new Tree();
  331. // Position relative does not work here in IE7
  332. DOM.setStyleAttribute(tree.getElement(), "position", "");
  333. TreeItem root = new TreeItem("Root problems");
  334. for (int i = 0; i < size; i++) {
  335. printLayoutError(valueMapArray.get(i), root, ac);
  336. }
  337. panel.add(tree);
  338. tree.addItem(root);
  339. }
  340. if (zeroHeightComponents.size() > 0 || zeroWidthComponents.size() > 0) {
  341. panel.add(new HTML("<h4> Client side notifications</h4>"
  342. + " <em>Following relative sized components where "
  343. + "rendered to zero size container on client side."
  344. + " Note that these are not necessary invalid "
  345. + "states. Just reported here as they might be.</em>"));
  346. if (zeroHeightComponents.size() > 0) {
  347. panel.add(new HTML(
  348. "<p><strong>Vertically zero size:</strong><p>"));
  349. printClientSideDetectedIssues(zeroHeightComponents, ac);
  350. }
  351. if (zeroWidthComponents.size() > 0) {
  352. panel.add(new HTML(
  353. "<p><strong>Horizontally zero size:</strong><p>"));
  354. printClientSideDetectedIssues(zeroWidthComponents, ac);
  355. }
  356. }
  357. log("************************");
  358. }
  359. private void printClientSideDetectedIssues(
  360. Set<Paintable> zeroHeightComponents, ApplicationConnection ac) {
  361. for (final Paintable paintable : zeroHeightComponents) {
  362. final Container layout = Util.getLayout((Widget) paintable);
  363. VerticalPanel errorDetails = new VerticalPanel();
  364. errorDetails.add(new Label("" + Util.getSimpleName(paintable)
  365. + " inside " + Util.getSimpleName(layout)));
  366. final CheckBox emphasisInUi = new CheckBox(
  367. "Emphasis components parent in UI (actual component is not visible)");
  368. emphasisInUi.addClickHandler(new ClickHandler() {
  369. public void onClick(ClickEvent event) {
  370. if (paintable != null) {
  371. Element element2 = ((Widget) layout).getElement();
  372. Widget.setStyleName(element2, "invalidlayout",
  373. emphasisInUi.getValue());
  374. }
  375. }
  376. });
  377. errorDetails.add(emphasisInUi);
  378. panel.add(errorDetails);
  379. }
  380. }
  381. private void printLayoutError(ValueMap valueMap, TreeItem parent,
  382. final ApplicationConnection ac) {
  383. final String pid = valueMap.getString("id");
  384. final Paintable paintable = ac.getPaintable(pid);
  385. TreeItem errorNode = new TreeItem();
  386. VerticalPanel errorDetails = new VerticalPanel();
  387. errorDetails.add(new Label(Util.getSimpleName(paintable) + " id: "
  388. + pid));
  389. if (valueMap.containsKey("heightMsg")) {
  390. errorDetails.add(new Label("Height problem: "
  391. + valueMap.getString("heightMsg")));
  392. }
  393. if (valueMap.containsKey("widthMsg")) {
  394. errorDetails.add(new Label("Width problem: "
  395. + valueMap.getString("widthMsg")));
  396. }
  397. final CheckBox emphasisInUi = new CheckBox("Emphasis component in UI");
  398. emphasisInUi.addClickHandler(new ClickHandler() {
  399. public void onClick(ClickEvent event) {
  400. if (paintable != null) {
  401. Element element2 = ((Widget) paintable).getElement();
  402. Widget.setStyleName(element2, "invalidlayout", emphasisInUi
  403. .getValue());
  404. }
  405. }
  406. });
  407. errorDetails.add(emphasisInUi);
  408. errorNode.setWidget(errorDetails);
  409. if (valueMap.containsKey("subErrors")) {
  410. HTML l = new HTML(
  411. "<em>Expand this node to show problems that may be dependent on this problem.</em>");
  412. errorDetails.add(l);
  413. JsArray<ValueMap> suberrors = valueMap
  414. .getJSValueMapArray("subErrors");
  415. for (int i = 0; i < suberrors.length(); i++) {
  416. ValueMap value = suberrors.get(i);
  417. printLayoutError(value, errorNode, ac);
  418. }
  419. }
  420. parent.addItem(errorNode);
  421. }
  422. }