Revision: 8718
Author: [email protected]
Date: Fri Sep  3 10:10:06 2010
Log: Add Late Loading support to xsiframe linker

Review at http://gwt-code-reviews.appspot.com/807801

http://code.google.com/p/google-web-toolkit/source/detail?r=8718

Modified:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/computeScriptBase.js
 /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.js
 /trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js

=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/computeScriptBase.js Mon Mar 22 09:13:22 2010 +++ /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/computeScriptBase.js Fri Sep 3 10:10:06 2010
@@ -24,24 +24,39 @@
  * on each side.
  */
 function computeScriptBase() {
-  var thisScript
-  ,markerId = "__gwt_marker___MODULE_NAME__"
-  ,markerScript;
-
+  // First, check if the meta properties give the baseUrl
   if (metaProps['baseUrl']) {
     base = metaProps['baseUrl'];
     return;
   }

-  $doc.write('<script id="' + markerId + '"></script>');
-  markerScript = $doc.getElementById(markerId);
-
- // Our script element is assumed to be the closest previous script element
-  // to the marker, so start at the marker and walk backwards until we find
-  // a script.
-  thisScript = markerScript && markerScript.previousSibling;
-  while (thisScript && thisScript.tagName != 'SCRIPT') {
-    thisScript = thisScript.previousSibling;
+  // The baseUrl will be similar to the URL for this script's URL
+  var thisScript;
+
+  // By default, this script looks like something/moduleName.nocache.js
+  // so look for a script tag that looks like that
+  var scriptTags = $doc.getElementsByTagName('script');
+  for (var i = 0; i < scriptTags.length; ++i) {
+    if (scriptTags[i].src.indexOf('__MODULE_NAME__.nocache.js') != -1) {
+      thisScript = scriptTags[i];
+    }
+  }
+
+ // If the user renamed their script tag, we'll use a fancier method to find
+  // it. Note that this will not work in the Late Loading case due to the
+  // document.write call.
+  if (!thisScript) {
+ // Put in a marker script element which should be the first script tag after + // the tag we're looking for. To find it, we start at the marker and walk
+    // backwards until we find a script.
+    var markerId = "__gwt_marker___MODULE_NAME__";
+    var markerScript;
+    $doc.write('<script id="' + markerId + '"></script>');
+    markerScript = $doc.getElementById(markerId);
+    thisScript = markerScript && markerScript.previousSibling;
+    while (thisScript && thisScript.tagName != 'SCRIPT') {
+      thisScript = thisScript.previousSibling;
+    }
   }

   // Gets the part of a url up to and including the 'path' portion.
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.js Fri Aug 27 17:16:41 2010 +++ /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted.js Fri Sep 3 10:10:06 2010
@@ -333,13 +333,20 @@

 doBrowserSpecificFixes();

-// DevMode currently only supports iframe based linkers
-var query = parent.location.search;
 if (!findPluginXPCOM()) {
- document.write('<embed id="pluginEmbed" type="application/x-gwt-hosted-mode" width="10" height="10">');
-  document.write('</embed>');
- document.write('<object id="pluginObject" CLASSID="CLSID:1D6156B6-002B-49E7-B5CA-C138FB843B4E">');
-  document.write('</object>');
+  var embed = document.createElement('embed');
+  embed.id = 'pluginEmbed';
+  embed.type = 'application/x-gwt-hosted-mode';
+  embed.width = '10';
+  embed.height = '20';
+
+  var obj = document.createElement('object');
+  obj.id = 'pluginObject';
+  obj.CLASSID = 'CLSID:1D6156B6-002B-49E7-B5CA-C138FB843B4E';
+
+  var dochead = doc.getElementsByTagName('head')[0];
+  dochead.append(embed);
+  dochead.append(obj);
 }

setTimeout(function() { $wnd[$moduleName].onScriptInstalled(gwtOnLoad) }, 1);
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js Fri Aug 27 17:16:41 2010 +++ /trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js Fri Sep 3 10:10:06 2010
@@ -56,24 +56,20 @@

   ; // end of global vars

-  $stats && $stats({
-    moduleName: '__MODULE_NAME__',
-    sessionId: $sessionId,
-    subSystem: 'startup',
-    evtGroup: 'bootstrap',
-    millis:(new Date()).getTime(),
-    type: 'begin',
-  });
-
-  // ------------------ TRUE GLOBALS ------------------
-
- // Maps to synchronize the loading of styles and scripts; resources are loaded - // only once, even when multiple modules depend on them. This API must not
-  // change across GWT versions.
-  if (!$wnd.__gwt_stylesLoaded) { $wnd.__gwt_stylesLoaded = {}; }
-  if (!$wnd.__gwt_scriptsLoaded) { $wnd.__gwt_scriptsLoaded = {}; }
+  sendStats('bootstrap', 'begin');

   // --------------- INTERNAL FUNCTIONS ---------------
+
+  function sendStats(evtGroupString, typeString) {
+    $stats && $stats({
+      moduleName: '__MODULE_NAME__',
+      sessionId: $sessionId,
+      subSystem: 'startup',
+      evtGroup: evtGroupString,
+      millis:(new Date()).getTime(),
+      type: typeString,
+    });
+  }

   function isHostedMode() {
     var result = false;
@@ -148,6 +144,53 @@
     // It should have installed its code immediately after being added.
     docbody.removeChild(script);
   }
+
+ // Setup code so that maybeCreateFrame() is called once the body is loaded
+  function setupWaitForBodyLoad() {
+    function isBodyLoaded() {
+      return (/loaded|complete/.test($doc.readyState));
+    }
+
+    if (isBodyLoaded()) {
+ // If this script is being added to an already loaded page, then just set
+      // the variable to true.
+      bodyDone = true;
+ // maybeCreateFrame will not do anything since we know the compiled script + // has not yet been downloaded, so we don't need to call it here like we
+      // do when bodyDone becomes true after a callback or timer.
+    }
+
+ // If the page is not already loaded, setup some listeners and timers to
+    // detect when it is done.
+    var onBodyDoneTimerId;
+    function onBodyDone() {
+      if (!bodyDone) {
+        bodyDone = true;
+        maybeCreateFrame();
+
+        if ($doc.removeEventListener) {
+          $doc.removeEventListener("DOMContentLoaded", onBodyDone, false);
+        }
+        if (onBodyDoneTimerId) {
+          clearInterval(onBodyDoneTimerId);
+        }
+      }
+    }
+
+    // For everyone that supports DOMContentLoaded.
+    if ($doc.addEventListener) {
+      $doc.addEventListener("DOMContentLoaded", function() {
+        onBodyDone();
+      }, false);
+    }
+
+    // Fallback. If onBodyDone() gets fired twice, it's not a big deal.
+    var onBodyDoneTimerId = setInterval(function() {
+      if (isBodyLoaded()) {
+        onBodyDone();
+      }
+    }, 50);
+  }

   __PROCESS_METAS__
   __COMPUTE_SCRIPT_BASE__
@@ -227,20 +270,13 @@
     }
gwtOnLoadFunc(onLoadErrorFunc, '__MODULE_NAME__', base, softPermutationId);
     // Record when the module EntryPoints return.
-    $stats && $stats({
-      moduleName: '__MODULE_NAME__',
-      sessionId: $sessionId,
-      subSystem: 'startup',
-      evtGroup: 'moduleStartup',
-      millis:(new Date()).getTime(),
-      type: 'end',
-    });
+    sendStats('moduleStartup', 'end');
   }

   // Install code pulled in via runAsync
   //
   __MODULE_FUNC__.installCode = installCode;
-
+
   // --------------- STRAIGHT-LINE CODE ---------------

   // do it early for compile/browse rebasing
@@ -249,14 +285,7 @@

   // --------------- WINDOW ONLOAD HOOK ---------------

-  $stats && $stats({
-    moduleName:'__MODULE_NAME__',
-    sessionId: $sessionId,
-    subSystem:'startup',
-    evtGroup: 'bootstrap',
-    millis:(new Date()).getTime(),
-    type: 'selectingPermutation'
-  });
+  sendStats('bootstrap', 'selectingPermutation');

   var strongName;
   if (!isHostedMode()) {
@@ -274,84 +303,19 @@
       return;
     }
   }
-
-  var onBodyDoneTimerId;
-  function onBodyDone() {
-    if (!bodyDone) {
-      bodyDone = true;
-// __MODULE_STYLES_BEGIN__
- // Style resources are injected here to prevent operation aborted errors on ie
-// __MODULE_STYLES_END__
-      maybeCreateFrame();
-
-      if ($doc.removeEventListener) {
-        $doc.removeEventListener("DOMContentLoaded", onBodyDone, false);
-      }
-      if (onBodyDoneTimerId) {
-        clearInterval(onBodyDoneTimerId);
-      }
-    }
-  }
-
-  // For everyone that supports DOMContentLoaded.
-  if ($doc.addEventListener) {
-    $doc.addEventListener("DOMContentLoaded", function() {
-      onBodyDone();
-    }, false);
-  }
-
-  // Fallback. If onBodyDone() gets fired twice, it's not a big deal.
-  var onBodyDoneTimerId = setInterval(function() {
-    if (/loaded|complete/.test($doc.readyState)) {
-      onBodyDone();
-    }
-  }, 50);
-
-  $stats && $stats({
-    moduleName:'__MODULE_NAME__',
-    sessionId: $sessionId,
-    subSystem:'startup',
-    evtGroup: 'bootstrap',
-    millis:(new Date()).getTime(),
-    type: 'end'
-  });
-
-  $stats && $stats({
-    moduleName:'__MODULE_NAME__',
-    sessionId: $sessionId,
-    subSystem:'startup',
-    evtGroup: 'loadExternalRefs',
-    millis:(new Date()).getTime(),
-    type: 'begin'
-  });
-
-// __MODULE_SCRIPTS_BEGIN__
-  // Script resources are injected here
-// __MODULE_SCRIPTS_END__
- // This is a bit ugly, but serves a purpose. We need to ensure that the stats - // script runs before the compiled script. If they are both doc.write()n in
-  // sequence, that should be the effect. Except on IE it turns out that a
- // script injected via doc.write() can execute immediately! Adding 'defer'
-  // attributes to both seemed to fix this, but caused startup problems for
-  // some apps. The final solution was simply to inject the compiled script
- // from *within* the stats script, guaranteeing order at the expense of near
-  // total inscrutability :(
-  var compiledScriptWrite = '';
+
+  setupWaitForBodyLoad();
+
+  sendStats('bootstrap', 'end');
+  sendStats('moduleStartup', 'moduleRequested');
+
   if (!isHostedMode()) {
- compiledScriptWrite = 'document.write("<script src=\\"' + base + strongName + '.cache.js\\"></scr" + "ipt>");';
-  }
-
-  $doc.write('<scr' + 'ipt><!-' + '-\n'
-    + 'window.__gwtStatsEvent && window.__gwtStatsEvent({'
- + 'moduleName:"__MODULE_NAME__", sessionId:window.__gwtStatsSessionId, subSystem:"startup",'
-    + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),'
-    + 'type: "end"});'
-    + 'window.__gwtStatsEvent && window.__gwtStatsEvent({'
- + 'moduleName:"__MODULE_NAME__", sessionId:window.__gwtStatsSessionId, subSystem:"startup",'
-    + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),'
-    + 'type: "moduleRequested"});'
-    + compiledScriptWrite
-    + '\n-' + '-></scr' + 'ipt>');
+    var script = document.createElement('script');
+    script.src = base + strongName + '.cache.js;'
+    $doc.getElementsByTagName('head')[0].appendChild(script);
+  } else {
+       maybeCreateFrame();
+  }
 }

 __MODULE_FUNC__();

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to