Reverting XHR changes to the std (iframe) linker. 
This patch effectively reverts r5538, r5530, r5523, r5517, r5393 and preserves r5605.
Code review: http://gwt-code-reviews.appspot.com/48808/show


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5691 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html b/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html
index e24b9be..3037377 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.html
@@ -4,21 +4,11 @@
 var $doc = $wnd.document;
 var $moduleName, $moduleBase
 ,$stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null;
-
-// The module to be loaded can be specified either through the url query
-// parameter (as done by the legacy HostedModeTemplate.js), or by specifying
-// window.name (as done by IFrameTemplate.js). When the former approach
-// is removed, we can drop the window.location.search part of this logic.
-var moduleFuncName = window.location.search.substring(1);
-if (!moduleFuncName || !$wnd[moduleFuncName]) {
-  moduleFuncName = window.name;
-}
-
-var moduleFunc = $wnd[moduleFuncName];
-var moduleName = moduleFunc ? moduleFunc.moduleName : "unknown";
-
 // Lightweight metrics
 if ($stats) {
+  var moduleFuncName = location.search.substr(1);
+  var moduleFunc = $wnd[moduleFuncName];
+  var moduleName = moduleFunc ? moduleFunc.moduleName : "unknown";
   $stats({moduleName:moduleName,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});
 }
 
@@ -255,5 +245,6 @@
   }
 }
 
-setTimeout($wnd[moduleFuncName].onScriptLoad, 1);
+query = window.location.search.substring(1);
+if (query && $wnd[query]) setTimeout($wnd[query].onScriptLoad, 1);
 --></script></body></html>
diff --git a/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js b/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js
index 51b97df..80c148d 100644
--- a/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js
+++ b/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js
@@ -23,7 +23,7 @@
   ,$stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null
 
   // These variables gate calling gwtOnLoad; all must be true to start
-  ,injectedScriptsDone, gwtCodeEvaluated, bodyDone, scriptRequestCompleted, gwtFrameCreated
+  ,scriptsDone, loadDone, bodyDone
 
   // If non-empty, an alternate base url for this module
   ,base = ''
@@ -41,16 +41,9 @@
   // the strong name of the cache.js file to load.
   ,answers = []
 
-  // Error functions.  Default unset in compiled mode, may be set by meta props
+  // Error functions.  Default unset in compiled mode, may be set by meta props.
   ,onLoadErrorFunc, propertyErrorFunc
 
-  // The frame that will contain the compiled script (created in
-  // maybeCreateGwtFrame())
-  ,scriptFrame
-  
-  // Holds the compiled script retreived via XHR until the body is loaded
-  ,compiledScript = ""
-
   ; // end of global vars
 
   $stats && $stats({
@@ -86,16 +79,13 @@
     return result;
   }
 
-  // Called by onScriptLoad(), onScriptInjectionDone(), maybeCreateGwtFrame(), 
-  // and onBodyDone(). It causes the specified module to be cranked up.
+  // Called by onScriptLoad(), onInjectionDone(), and onload(). It causes
+  // the specified module to be cranked up.
   //
-  var moduleStarted = false;
   function maybeStartModule() {
-    if (bodyDone && injectedScriptsDone && gwtCodeEvaluated && gwtFrameCreated && !moduleStarted) {
-      moduleStarted = true;
-
-      var frameWnd = scriptFrame.contentWindow;
-
+    if (scriptsDone && loadDone) {
+      var iframe = $doc.getElementById('__MODULE_NAME__');
+      var frameWnd = iframe.contentWindow;
       // inject hosted mode property evaluation function
       if (isHostedMode()) {
         frameWnd.__gwt_getProperty = function(name) {
@@ -284,83 +274,32 @@
     throw null;
   }
 
-  // Creates a new XMLHttpRequest object. Used by fetchCompiledScript().
-  //
-  function newXhr() {
-    // This is the same logic as in GWT's XMLHttpRequest wrapper. The 'else'
-    // case is needed primarily for old IEs.
-    if (window.XMLHttpRequest) {
-      return new XMLHttpRequest();
-    } else {
-      try {
-        return new ActiveXObject('MSXML2.XMLHTTP.3.0');
-      } catch (e) {
-        return new ActiveXObject("Microsoft.XMLHTTP");
-      }
-    }
-  }
-
-  // Fetches the compiled script via XHR, saving it to 'compiledScript'
-  // to be added to the page later.
-  //
-  function fetchCompiledScript() {
-    $stats && $stats({
-      moduleName:'__MODULE_NAME__', 
-      subSystem:'startup', 
-      evtGroup: 'moduleStartup', 
-      millis:(new Date()).getTime(), 
-      type: 'moduleRequested'
-    });
-
-    // Fetch the contents via XHR.
-    var xhr = newXhr();
-    xhr.open('GET', base + initialHtml);
-    xhr.onreadystatechange = function() {
-      // 4 == DONE
-      if (xhr.readyState == 4) {
-        compiledScript = xhr.responseText;
-        xhr = null;
-        scriptRequestCompleted = true;
-        maybeCreateGwtFrame();
-      }
-    };
-    xhr.send(null);
-  }
-
-  // This is gated by bodyDone because we can't add elements to the
-  // page until the body is ready. It's also gated by 'scriptRequestCompleted'
-  // so it will not fire until the XHR returns, in case onBodyDone happens 
-  // first.
-  function maybeCreateGwtFrame() {
-    if (bodyDone && scriptRequestCompleted && !gwtFrameCreated) {
-      // Create the script frame, making sure it's invisible, but not
-      // "display:none", which keeps some browsers from running code in it.
-      scriptFrame = document.createElement('iframe');
-      scriptFrame.src = 'javascript:""';
-      scriptFrame.id = '__MODULE_NAME__';
-      scriptFrame.style.cssText = 'position:absolute; width:0; height:0; border:none';
-      scriptFrame.tabIndex = -1;
-      document.body.appendChild(scriptFrame);
-
-      // Expose the module function via the iframe's window.name property
-      // (this is needed for the compiled script to call back into
-      //  onScriptLoad()).
-      var win = scriptFrame.contentWindow;
-      if (isHostedMode()) {
-        win.name = '__MODULE_FUNC__';
-      }
-
-      // Set this *before* calling doc.write(), because the linux hosted-mode
-      // browser sometimes doesn't properly return from doc.write() if there are
-      // a large number of script blocks (even though it works fine). Go figure.
-      gwtFrameCreated = true;
-
-      // Inject the fetched script into the script frame.
-      // (this script will call onScriptLoad())
-      var doc = win.document;
-      doc.open();
-      doc.write(compiledScript);
-      doc.close();
+  var frameInjected;
+  function maybeInjectFrame() {
+    if (!frameInjected) {
+      frameInjected = true;
+      var iframe = $doc.createElement('iframe');
+      // Prevents mixed mode security in IE6/7.
+      iframe.src = "javascript:''";
+      iframe.id = "__MODULE_NAME__";
+      iframe.style.cssText = "position:absolute;width:0;height:0;border:none";
+      iframe.tabIndex = -1;
+      // Due to an IE6/7 refresh quirk, this must be an appendChild.
+      $doc.body.appendChild(iframe);
+      
+      /* 
+       * The src has to be set after the iframe is attached to the DOM to avoid
+       * refresh quirks in Safari.  We have to use the location.replace trick to
+       * avoid FF2 refresh quirks.
+       */
+      $stats && $stats({
+        moduleName:'__MODULE_NAME__', 
+        subSystem:'startup', 
+        evtGroup: 'moduleStartup', 
+        millis:(new Date()).getTime(), 
+        type: 'moduleRequested'
+      });
+      iframe.contentWindow.location.replace(base + initialHtml);
     }
   }
 
@@ -374,17 +313,21 @@
   // Called when the compiled script identified by moduleName is done loading.
   //
   __MODULE_FUNC__.onScriptLoad = function() {
-    // Mark this module's script as done loading and (possibly) start the
-    // module.
-    gwtCodeEvaluated = true;
-    maybeStartModule();
+    // IE7 bookmark bug. A phantom (presumably cached) version of our compiled iframe
+    // can call onScriptLoad before we even properly inject the iframe. So if this is
+    // called before the frame was injected ... it is completely bogus.
+    if (frameInjected) {
+      // Mark this module's script as done loading and (possibly) start the module.
+      loadDone = true;
+      maybeStartModule();
+    }
   }
 
   // Called when the script injection is complete.
   //
-  __MODULE_FUNC__.onScriptInjectionDone = function() {
+  __MODULE_FUNC__.onInjectionDone = function() {
     // Mark this module's script injection done and (possibly) start the module.
-    injectedScriptsDone = true;
+    scriptsDone = true;
     $stats && $stats({
       moduleName:'__MODULE_NAME__', 
       subSystem:'startup', 
@@ -408,14 +351,13 @@
       $wnd.location.reload();
       return;
     }
-
-    initialHtml = "hosted.html";
+    initialHtml = "hosted.html?__MODULE_FUNC__";
     strongName = "";
   }
 
   processMetas();
 
-  // ------- SELECT PERMUTATION AND FETCH SCRIPT -------
+  // --------------- WINDOW ONLOAD HOOK ---------------
 
   $stats && $stats({
     moduleName:'__MODULE_NAME__', 
@@ -437,16 +379,10 @@
     }
   }
 
-  // Start the request for the compiled script.
-  fetchCompiledScript();
-
-  // --------------- WINDOW ONLOAD HOOK ---------------
-
   var onBodyDoneTimerId;
   function onBodyDone() {
     if (!bodyDone) {
       bodyDone = true;
-      maybeCreateGwtFrame();
 // __MODULE_STYLES_BEGIN__
      // Style resources are injected here to prevent operation aborted errors on ie
 // __MODULE_STYLES_END__
@@ -464,6 +400,7 @@
   // For everyone that supports DOMContentLoaded.
   if ($doc.addEventListener) {
     $doc.addEventListener("DOMContentLoaded", function() {
+      maybeInjectFrame();
       onBodyDone();
     }, false);
   }
@@ -471,6 +408,7 @@
   // Fallback. If onBodyDone() gets fired twice, it's not a big deal.
   var onBodyDoneTimerId = setInterval(function() {
     if (/loaded|complete/.test($doc.readyState)) {
+      maybeInjectFrame();
       onBodyDone();
     }
   }, 50);
@@ -498,7 +436,7 @@
   // The 'defer' attribute here is a workaround for strange IE behavior where
   // <script> tags that are doc.writ()en execute *immediately*, rather than
   // in document-order, as they should. It has no effect on other browsers.
-  $doc.write('<script defer="defer">__MODULE_FUNC__.onScriptInjectionDone(\'__MODULE_NAME__\')</script>');
+  $doc.write('<script defer="defer">__MODULE_FUNC__.onInjectionDone(\'__MODULE_NAME__\')</script>');
 }
 
 __MODULE_FUNC__();