Set module base url to make GWT RPC work with -superDevMode

Bug: issue 8924
Change-Id: If5121398f1fb5c77a687968bda8cdc65abedc4c2
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_lib.js b/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_lib.js
index d97482f..e9bbdf3 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_lib.js
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_lib.js
@@ -333,3 +333,41 @@
 
 //Export MetaTagParser to namespace
 $namespace.lib.MetaTagParser = MetaTagParser;
+
+/**
+ * BaseUrlProvider provides the url to the original server that the app has been loaded from.
+ * This is not the url of super dev mode.
+ *
+ * @constructor
+ * @param {string} moduleName - the module for which we should determine the base url.
+ */
+function BaseUrlProvider(moduleName) {
+  this.__moduleName = moduleName;
+}
+
+BaseUrlProvider.prototype.__getScriptTags = function() {
+  return $doc.getElementsByTagName('script');
+};
+
+BaseUrlProvider.prototype.getBaseUrl = function() {
+  var expectedSuffix = this.__moduleName + '.nocache.js';
+  var scriptTags = this.__getScriptTags();
+  for (var i = 0;; i++) {
+    var tag = scriptTags[i];
+    if (!tag) {
+      break;
+    }
+    var candidate = tag.src;
+    var lastMatch = candidate.lastIndexOf(expectedSuffix);
+    if (lastMatch == candidate.length - expectedSuffix.length) {
+      // Assumes that either the URL is absolute, or it's relative
+      // and the html file is hosted by this code server.
+      return candidate.substring(0, lastMatch);
+    }
+  }
+
+  throw 'Unable to compute base url for module: ' + this.__moduleName;
+};
+
+//Export BaseUrlProvider to namespace
+$namespace.lib.BaseUrlProvider = BaseUrlProvider;
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_main.js b/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_main.js
index 16f05d8..d8d661f 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_main.js
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/recompile_main.js
@@ -17,6 +17,7 @@
 var Dialog = $namespace.lib.Dialog;
 var PropertyHelper = $namespace.lib.PropertyHelper;
 var Recompiler = $namespace.lib.Recompiler;
+var BaseUrlProvider = $namespace.lib.BaseUrlProvider;
 //Publish a global variable to let others know that we have been loaded
 $wnd.__gwt_sdm = $wnd.__gwt_sdm || {};
 $wnd.__gwt_sdm.loaded = true;
@@ -34,6 +35,7 @@
   this.__moduleName = moduleName;
   this.__dialog = new Dialog();
   this.__recompiler = new Recompiler(moduleName, propertyHelper.computeBindingProperties());
+  this.__baseUrlProvider = new BaseUrlProvider(moduleName);
 }
 
 /**
@@ -41,6 +43,10 @@
  */
 Main.prototype.compile = function() {
   var that = this;
+  // Export the module base of the server running the backend. (Returned by GWT.getModuleBaseURL.)
+  var moduleBaseKey = '__gwtDevModeHook:' + this.__moduleName + ':moduleBase';
+  $wnd[moduleBaseKey] = this.__baseUrlProvider.getBaseUrl();
+
   this.__dialog.clear();
   this.__dialog.add(this.__dialog.createTextElement("div", "12pt", "Compiling " + this.__moduleName));
   this.__dialog.show();
diff --git a/dev/codeserver/javatests/com/google/gwt/dev/codeserver/client/CodeServerGwtTest.java b/dev/codeserver/javatests/com/google/gwt/dev/codeserver/client/CodeServerGwtTest.java
index 9976999..03a538d 100644
--- a/dev/codeserver/javatests/com/google/gwt/dev/codeserver/client/CodeServerGwtTest.java
+++ b/dev/codeserver/javatests/com/google/gwt/dev/codeserver/client/CodeServerGwtTest.java
@@ -152,6 +152,23 @@
     assertStringEquals('test2', props.test1);
   }-*/;
 
+  public native void testBaseUrlProvider () /*-{
+    var assertStringEquals = @CodeServerGwtTest::assertEquals(Ljava/lang/String;Ljava/lang/String;);
+    var BaseUrlProvider = $wnd.namespace.lib.BaseUrlProvider;
+    var baseUrlProvider = new BaseUrlProvider('testModule');
+
+    baseUrlProvider.__getScriptTags = function() {
+      return [
+        {src: 'http://localhost:9876/somepath/testModule.recompile.nocache.js'},
+        {src: 'http://localhost:8888/somepath/testModule.nocache.js'},
+        {src: 'http://localhost:9876/somepath/testModule.recompile.nocache.js'}
+      ];
+    };
+
+    assertStringEquals('http://localhost:8888/somepath/',
+        baseUrlProvider.getBaseUrl());
+  }-*/;
+
   private void ensureJsInjected() {
     if(injected) {
       return;