--- /dev/null
+package com.vaadin.terminal.gwt.client;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.JavaScriptObject;\r
+import com.google.gwt.http.client.UrlBuilder;\r
+import com.google.gwt.jsonp.client.JsonpRequestBuilder;\r
+import com.google.gwt.storage.client.Storage;\r
+import com.google.gwt.user.client.Window.Location;\r
+import com.google.gwt.user.client.rpc.AsyncCallback;\r
+import com.vaadin.terminal.gwt.client.ui.notification.VNotification;\r
+import com.vaadin.terminal.gwt.client.ui.notification.VNotification.EventListener;\r
+import com.vaadin.terminal.gwt.client.ui.notification.VNotification.HideEvent;\r
+\r
+/**\r
+ * Class that enables SuperDevMode using a ?superdevmode parameter in the url.\r
+ * \r
+ * @author Vaadin Ltd\r
+ * @version @VERSION@\r
+ * @since 7.0\r
+ * \r
+ */\r
+public class SuperDevMode {\r
+\r
+ private static final int COMPILE_TIMEOUT_IN_SECONDS = 60;\r
+ protected static final String SKIP_RECOMPILE = "VaadinSuperDevMode_skip_recompile";\r
+\r
+ public static class RecompileResult extends JavaScriptObject {\r
+ protected RecompileResult() {\r
+\r
+ }\r
+\r
+ public final native boolean ok()\r
+ /*-{\r
+ return this.status == "ok";\r
+ }-*/;\r
+ }\r
+\r
+ private static void recompileWidgetsetAndStartInDevMode(\r
+ final String serverUrl) {\r
+ VConsole.log("Recompiling widgetset using<br/>" + serverUrl\r
+ + "<br/>and then reloading in super dev mode");\r
+ VNotification n = new VNotification();\r
+ n.show("<b>Recompiling widgetset, this should not take too long</b>",\r
+ VNotification.CENTERED, VNotification.STYLE_SYSTEM);\r
+\r
+ JsonpRequestBuilder b = new JsonpRequestBuilder();\r
+ b.setCallbackParam("_callback");\r
+ b.setTimeout(COMPILE_TIMEOUT_IN_SECONDS * 1000);\r
+ b.requestObject(serverUrl + "recompile/" + GWT.getModuleName() + "?"\r
+ + getRecompileParameters(GWT.getModuleName()),\r
+ new AsyncCallback<RecompileResult>() {\r
+\r
+ public void onSuccess(RecompileResult result) {\r
+ VConsole.log("JSONP compile call successful");\r
+\r
+ if (!result.ok()) {\r
+ VConsole.log("* result: " + result);\r
+ failed();\r
+ return;\r
+ }\r
+\r
+ setSession(\r
+ getSuperDevModeHookKey(),\r
+ getSuperDevWidgetSetUrl(GWT.getModuleName(),\r
+ serverUrl));\r
+ setSession(SKIP_RECOMPILE, "1");\r
+\r
+ VConsole.log("* result: OK. Reloading");\r
+ Location.reload();\r
+ }\r
+\r
+ public void onFailure(Throwable caught) {\r
+ VConsole.error("JSONP compile call failed");\r
+ // Don't log exception as they are shown as\r
+ // notifications\r
+ VConsole.error(Util.getSimpleName(caught) + ": "\r
+ + caught.getMessage());\r
+ failed();\r
+\r
+ }\r
+\r
+ private void failed() {\r
+ VNotification n = new VNotification();\r
+ n.addEventListener(new EventListener() {\r
+\r
+ public void notificationHidden(HideEvent event) {\r
+ recompileWidgetsetAndStartInDevMode(serverUrl);\r
+ }\r
+ });\r
+ n.show("Recompilation failed.<br/>"\r
+ + "Make sure CodeServer is running, "\r
+ + "check its output and click to retry",\r
+ VNotification.CENTERED,\r
+ VNotification.STYLE_SYSTEM);\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ protected static String getSuperDevWidgetSetUrl(String widgetsetName,\r
+ String serverUrl) {\r
+ return serverUrl + GWT.getModuleName() + "/" + GWT.getModuleName()\r
+ + ".nocache.js";\r
+ }\r
+\r
+ private native static String getRecompileParameters(String moduleName)\r
+ /*-{\r
+ var prop_map = $wnd.__gwt_activeModules[moduleName].bindings();\r
+ \r
+ // convert map to URL parameter string\r
+ var props = [];\r
+ for (var key in prop_map) {\r
+ props.push(encodeURIComponent(key) + '=' + encodeURIComponent(prop_map[key]))\r
+ }\r
+ \r
+ return props.join('&') + '&';\r
+ }-*/;\r
+\r
+ private static void setSession(String key, String value) {\r
+ Storage.getSessionStorageIfSupported().setItem(key, value);\r
+ }\r
+\r
+ private static String getSession(String key) {\r
+ return Storage.getSessionStorageIfSupported().getItem(key);\r
+ }\r
+\r
+ private static void removeSession(String key) {\r
+ Storage.getSessionStorageIfSupported().removeItem(key);\r
+ }\r
+\r
+ protected static void disableDevModeAndReload() {\r
+ removeSession(getSuperDevModeHookKey());\r
+ redirect(false);\r
+ }\r
+\r
+ protected static void redirect(boolean devModeOn) {\r
+ UrlBuilder createUrlBuilder = Location.createUrlBuilder();\r
+ if (!devModeOn) {\r
+ createUrlBuilder.removeParameter("superdevmode");\r
+ } else {\r
+ createUrlBuilder.setParameter("superdevmode", "");\r
+ }\r
+\r
+ Location.assign(createUrlBuilder.buildString());\r
+\r
+ }\r
+\r
+ private static String getSuperDevModeHookKey() {\r
+ String widgetsetName = GWT.getModuleName();\r
+ final String superDevModeKey = "__gwtDevModeHook:" + widgetsetName;\r
+ return superDevModeKey;\r
+ }\r
+\r
+ private static boolean hasSession(String key) {\r
+ return getSession(key) != null;\r
+ }\r
+\r
+ /**\r
+ * The URL of the code server. The default URL (http://localhost:9876/) will\r
+ * be used if this is empty or null.\r
+ * \r
+ * @param serverUrl\r
+ * The url of the code server or null to use the default\r
+ * @return true if recompile started, false if we are running in\r
+ * SuperDevMode\r
+ */\r
+ protected static boolean recompileIfNeeded(String serverUrl) {\r
+ if (serverUrl == null || "".equals(serverUrl)) {\r
+ serverUrl = "http://localhost:9876/";\r
+ } else {\r
+ serverUrl = "http://" + serverUrl + "/";\r
+ }\r
+\r
+ if (hasSession(SKIP_RECOMPILE)) {\r
+ VConsole.log("Running in SuperDevMode");\r
+ // When we get here, we are running in super dev mode\r
+\r
+ // Remove the flag so next reload will recompile\r
+ removeSession(SKIP_RECOMPILE);\r
+\r
+ // Remove the gwt flag so we will not end up in dev mode if we\r
+ // remove the url parameter manually\r
+ removeSession(getSuperDevModeHookKey());\r
+\r
+ return false;\r
+ }\r
+\r
+ recompileWidgetsetAndStartInDevMode(serverUrl);\r
+ return true;\r
+ }\r
+\r
+ protected static boolean isSuperDevModeEnabledInModule() {\r
+ String moduleName = GWT.getModuleName();\r
+ return isSuperDevModeEnabledInModule(moduleName);\r
+ }\r
+\r
+ protected native static boolean isSuperDevModeEnabledInModule(\r
+ String moduleName)\r
+ /*-{\r
+ if (!$wnd.__gwt_activeModules)\r
+ return false;\r
+ var mod = $wnd.__gwt_activeModules[moduleName];\r
+ if (!mod)\r
+ return false;\r
+\r
+ if (mod.superdevmode) {\r
+ // Running in super dev mode already, it is supported\r
+ return true;\r
+ }\r
+\r
+ return mod.canRedirect;\r
+ }-*/;\r
+\r
+ /**\r
+ * Enables SuperDevMode if the url contains the "superdevmode" parameter.\r
+ * <p>\r
+ * The caller should not continue initialization of the application if this\r
+ * method returns true. The application will be restarted once compilation\r
+ * is done and then this method will return false.\r
+ * </p>\r
+ * \r
+ * @return true if a recompile operation has started and the page will be\r
+ * reloaded once it is done, false if no recompilation will be done.\r
+ */\r
+ public static boolean enableBasedOnParameter() {\r
+ String superDevModeParameter = Location.getParameter("superdevmode");\r
+ if (superDevModeParameter != null) {\r
+ // Need to check the recompile flag also because if we are running\r
+ // in super dev mode, as a result of the recompile, the enabled\r
+ // check will fail...\r
+ if (!isSuperDevModeEnabledInModule()) {\r
+ showError("SuperDevMode is not enabled for this module/widgetset.<br/>"\r
+ + "Ensure that your module definition (.gwt.xml) contains <br/>"\r
+ + "<add-linker name="xsiframe"/><br/>"\r
+ + "<set-configuration-property name="devModeRedirectEnabled" value="true" /><br/>");\r
+ return false;\r
+ }\r
+ return SuperDevMode.recompileIfNeeded(superDevModeParameter);\r
+ }\r
+ return false;\r
+ }\r
+\r
+ private static void showError(String message) {\r
+ VNotification n = new VNotification();\r
+ n.show(message, VNotification.CENTERED_TOP, VNotification.STYLE_SYSTEM);\r
+ }\r
+}\r
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.UmbrellaException;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.UrlBuilder;
import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
private Button savePosition = new Button("S");
private Button highlight = new Button("H");
private Button connectorStats = new Button("CS");
- private CheckBox hostedMode = new CheckBox("GWT");
+ private CheckBox devMode = new CheckBox("Dev");
+ private CheckBox superDevMode = new CheckBox("SDev");
private CheckBox autoScroll = new CheckBox("Autoscroll ");
private HorizontalPanel actions;
private boolean collapsed = false;
savePosition
.setTitle("Saves the position and size of debug console to a cookie");
actions.add(autoScroll);
- actions.add(hostedMode);
- if (Location.getParameter("gwt.codesvr") != null) {
- hostedMode.setValue(true);
- }
- hostedMode.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- if (hostedMode.getValue()) {
- addHMParameter();
- } else {
- removeHMParameter();
- }
- }
-
- private void addHMParameter() {
- UrlBuilder createUrlBuilder = Location.createUrlBuilder();
- createUrlBuilder.setParameter("gwt.codesvr",
- "localhost:9997");
- Location.assign(createUrlBuilder.buildString());
- }
-
- private void removeHMParameter() {
- UrlBuilder createUrlBuilder = Location.createUrlBuilder();
- createUrlBuilder.removeParameter("gwt.codesvr");
- Location.assign(createUrlBuilder.buildString());
-
- }
- });
+ addDevMode();
+ addSuperDevMode();
autoScroll
.setTitle("Automatically scroll so that new messages are visible");
}
+ private void addSuperDevMode() {
+ final Storage sessionStorage = Storage.getSessionStorageIfSupported();
+ if (sessionStorage == null) {
+ return;
+ }
+ actions.add(superDevMode);
+ if (Location.getParameter("superdevmode") != null) {
+ superDevMode.setValue(true);
+ }
+ superDevMode.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
+
+ public void onValueChange(ValueChangeEvent<Boolean> event) {
+ SuperDevMode.redirect(event.getValue());
+ }
+
+ });
+
+ }
+
+ private void addDevMode() {
+ actions.add(devMode);
+ if (Location.getParameter("gwt.codesvr") != null) {
+ devMode.setValue(true);
+ }
+ devMode.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ if (devMode.getValue()) {
+ addHMParameter();
+ } else {
+ removeHMParameter();
+ }
+ }
+
+ private void addHMParameter() {
+ UrlBuilder createUrlBuilder = Location.createUrlBuilder();
+ createUrlBuilder.setParameter("gwt.codesvr", "localhost:9997");
+ Location.assign(createUrlBuilder.buildString());
+ }
+
+ private void removeHMParameter() {
+ UrlBuilder createUrlBuilder = Location.createUrlBuilder();
+ createUrlBuilder.removeParameter("gwt.codesvr");
+ Location.assign(createUrlBuilder.buildString());
+
+ }
+ });
+ }
+
protected void dumpConnectorInfo(ApplicationConnection a) {
RootConnector root = a.getRootConnector();
log("================");