Revision: 8565
Author: [email protected]
Date: Wed Aug 18 11:12:36 2010
Log: Add DevMode support for the xsiframe linker
Review at http://gwt-code-reviews.appspot.com/779801
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8565
Added:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted_xsiframe.html
Modified:
/trunk/dev/core/src/com/google/gwt/core/ext/Linker.java
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js
/trunk/dev/core/src/com/google/gwt/core/linker/IFrameLinker.java
/trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js
/trunk/user/src/com/google/gwt/junit/JUnitShell.java
/trunk/user/test/com/google/gwt/core/ext/test/CrossSiteIframeLinkerTest.java
=======================================
--- /dev/null
+++
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/hosted_xsiframe.html
Wed Aug 18 11:12:36 2010
@@ -0,0 +1,350 @@
+<html>
+<head><script>
+var $wnd = parent;
+var $doc = $wnd.document;
+var $moduleName, $moduleBase, $entry
+,$stats = $wnd.__gwtStatsEvent ? function(a) {return
$wnd.__gwtStatsEvent(a);} : null
+,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;
+// Lightweight metrics
+if ($stats) {
+ var moduleFuncName = location.search.substr(1);
+ var moduleFunc = $wnd[moduleFuncName];
+ var moduleName = moduleFunc ? moduleFunc.moduleName : "unknown";
+
$stats({moduleName:moduleName,sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new
Date()).getTime(),type:'moduleEvalStart'});
+}
+var $hostedHtmlVersion="2.1";
+
+var gwtOnLoad;
+var $hosted = "localhost:9997";
+
+function loadIframe(url) {
+ var topDoc = window.top.document;
+
+ // create an iframe
+ var iframeDiv = topDoc.createElement("div");
+ iframeDiv.innerHTML = "<iframe scrolling=no frameborder=0 src='" + url
+ "'>";
+ var iframe = iframeDiv.firstChild;
+
+ // mess with the iframe style a little
+ var iframeStyle = iframe.style;
+ iframeStyle.position = "absolute";
+ iframeStyle.borderWidth = "0";
+ iframeStyle.left = "0";
+ iframeStyle.top = "0";
+ iframeStyle.width = "100%";
+ iframeStyle.backgroundColor = "#ffffff";
+ iframeStyle.zIndex = "1";
+ iframeStyle.height = "100%";
+
+ // update the top window's document's body's style
+ var hostBodyStyle = window.top.document.body.style;
+ hostBodyStyle.margin = "0";
+ hostBodyStyle.height = iframeStyle.height;
+ hostBodyStyle.overflow = "hidden";
+
+ // insert the iframe
+ topDoc.body.insertBefore(iframe, topDoc.body.firstChild);
+}
+
+var ua = navigator.userAgent.toLowerCase();
+if (ua.indexOf("gecko") != -1) {
+ // install eval wrapper on FF to avoid EvalError problem
+ var __eval = window.eval;
+ window.eval = function(s) {
+ return __eval(s);
+ }
+}
+if (ua.indexOf("chrome") != -1) {
+ // work around __gwt_ObjectId appearing in JS objects
+ var hop = Object.prototype.hasOwnProperty;
+ Object.prototype.hasOwnProperty = function(prop) {
+ return prop != "__gwt_ObjectId" && hop.call(this, prop);
+ };
+ // do the same in our parent as well -- see issue 4486
+ // NOTE: this will have to be changed when we support non-iframe-based
DevMode
+ var hop2 = parent.Object.prototype.hasOwnProperty;
+ parent.Object.prototype.hasOwnProperty = function(prop) {
+ return prop != "__gwt_ObjectId" && hop2.call(this, prop);
+ };
+}
+
+// wrapper to call JS methods, which we need both to be able to supply a
+// different this for method lookup and to get the exception back
+function __gwt_jsInvoke(thisObj, methodName) {
+ try {
+ var args = Array.prototype.slice.call(arguments, 2);
+ return [0, window[methodName].apply(thisObj, args)];
+ } catch (e) {
+ return [1, e];
+ }
+}
+
+var __gwt_javaInvokes = [];
+function __gwt_makeJavaInvoke(argCount) {
+ return __gwt_javaInvokes[argCount] || __gwt_doMakeJavaInvoke(argCount);
+}
+
+function __gwt_doMakeJavaInvoke(argCount) {
+ // IE6 won't eval() anonymous functions except as r-values
+ var argList = "";
+ for (var i = 0; i < argCount; i++) {
+ argList += ",p" + i;
+ }
+ var argListNoComma = argList.substring(1);
+
+ return eval(
+ "__gwt_javaInvokes[" + argCount + "] =\n" +
+ " function(thisObj, dispId" + argList + ") {\n" +
+ " var result = __static(dispId, thisObj" + argList + ");\n" +
+ " if (result[0]) {\n" +
+ " throw result[1];\n" +
+ " } else {\n" +
+ " return result[1];\n" +
+ " }\n" +
+ " }\n"
+ );
+}
+
+/*
+ * This is used to create tear-offs of Java methods. Each function
corresponds
+ * to exactly one dispId, and also embeds the argument count. We get
the "this"
+ * value from the context in which the function is being executed.
+ * Function-object identity is preserved by caching in a sparse array.
+ */
+var __gwt_tearOffs = [];
+var __gwt_tearOffGenerators = [];
+function __gwt_makeTearOff(proxy, dispId, argCount) {
+ return __gwt_tearOffs[dispId] || __gwt_doMakeTearOff(dispId, argCount);
+}
+
+function __gwt_doMakeTearOff(dispId, argCount) {
+ return __gwt_tearOffs[dispId] =
+ (__gwt_tearOffGenerators[argCount] ||
__gwt_doMakeTearOffGenerator(argCount))(dispId);
+}
+
+function __gwt_doMakeTearOffGenerator(argCount) {
+ // IE6 won't eval() anonymous functions except as r-values
+ var argList = "";
+ for (var i = 0; i < argCount; i++) {
+ argList += ",p" + i;
+ }
+ var argListNoComma = argList.substring(1);
+
+ return eval(
+ "__gwt_tearOffGenerators[" + argCount + "] =\n" +
+ " function(dispId) {\n" +
+ " return function(" + argListNoComma + ") {\n" +
+ " var result = __static(dispId, this" + argList + ");\n" +
+ " if (result[0]) {\n" +
+ " throw result[1];\n" +
+ " } else {\n" +
+ " return result[1];\n" +
+ " }\n" +
+ " }\n" +
+ " }\n"
+ );
+}
+
+function __gwt_makeResult(isException, result) {
+ return [isException, result];
+}
+
+function __gwt_disconnected() {
+ // Prevent double-invocation.
+ window.__gwt_disconnected = new Function();
+ // Do it in a timeout so we can be sure we have a clean stack.
+ window.setTimeout(__gwt_disconnected_impl, 1);
+}
+
+function __gwt_disconnected_impl() {
+ __gwt_displayGlassMessage('GWT Code Server Disconnected',
+ 'Most likely, you closed GWT Development Mode. Or, you might have
lost '
+ + 'network connectivity. To fix this, try restarting GWT Development
Mode and '
+ + '<a style="color: #FFFFFF; font-weight: bold;"
href="javascript:location.reload()">'
+ + 'REFRESH</a> this page.');
+}
+
+// Note this method is also used by ModuleSpace.java
+function __gwt_displayGlassMessage(summary, details) {
+ var topWin = window.top;
+ var topDoc = topWin.document;
+ var outer = topDoc.createElement("div");
+ // Do not insert whitespace or outer.firstChild will get a text node.
+ outer.innerHTML =
+ '<div
style="position:absolute;z-index:2147483646;left:0px;top:0px;right:0px;bottom:0px;filter:alpha(opacity=75);opacity:0.75;background-color:#000000;"></div>'
+
+ '<div
style="position:absolute;z-index:2147483647;left:50px;top:50px;width:600px;color:#FFFFFF;font-family:verdana;">'
+
+ '<div style="font-size:30px;font-weight:bold;">' + summary
+ '</div>' +
+ '<p style="font-size:15px;">' + details + '</p>' +
+ '</div>'
+ ;
+ topDoc.body.appendChild(outer);
+ var glass = outer.firstChild;
+ var glassStyle = glass.style;
+
+ // Scroll to the top and remove scrollbars.
+ topWin.scrollTo(0, 0);
+ if (topDoc.compatMode == "BackCompat") {
+ topDoc.body.style["overflow"] = "hidden";
+ } else {
+ topDoc.documentElement.style["overflow"] = "hidden";
+ }
+
+ // Steal focus.
+ glass.focus();
+
+ if ((navigator.userAgent.indexOf("MSIE") >= 0) && (topDoc.compatMode
== "BackCompat")) {
+ // IE quirks mode doesn't support right/bottom, but does support this.
+ glassStyle.width = "125%";
+ glassStyle.height = "100%";
+ } else if (navigator.userAgent.indexOf("MSIE 6") >= 0) {
+ // IE6 doesn't have a real standards mode, so we have to use hacks.
+ glassStyle.width = "125%"; // Get past scroll bar area.
+ // Nasty CSS; onresize would be better but the outer window won't let
us add a listener IE.
+
glassStyle.setExpression("height", "document.documentElement.clientHeight");
+ }
+
+ $doc.title = summary + " [" + $doc.title + "]";
+}
+
+function findPluginObject() {
+ try {
+ return document.getElementById('pluginObject');
+ } catch (e) {
+ return null;
+ }
+}
+
+function findPluginEmbed() {
+ try {
+ return document.getElementById('pluginEmbed')
+ } catch (e) {
+ return null;
+ }
+}
+
+function findPluginXPCOM() {
+ try {
+ return __gwt_HostedModePlugin;
+ } catch (e) {
+ return null;
+ }
+}
+
+gwtOnLoad = function(errFn, modName, modBase){
+ $moduleName = modName;
+ $moduleBase = modBase;
+
+ // Note that the order is important
+ var pluginFinders = [
+ findPluginXPCOM,
+ findPluginObject,
+ findPluginEmbed,
+ ];
+ var topWin = window.top;
+ var url = topWin.location.href;
+ if (!topWin.__gwt_SessionID) {
+ var ASCII_EXCLAMATION = 33;
+ var ASCII_TILDE = 126;
+ var chars = [];
+ for (var i = 0; i < 16; ++i) {
+ chars.push(Math.floor(ASCII_EXCLAMATION
+ + Math.random() * (ASCII_TILDE - ASCII_EXCLAMATION + 1)));
+ }
+ topWin.__gwt_SessionID = String.fromCharCode.apply(null, chars);
+ }
+ var plugin = null;
+ for (var i = 0; i < pluginFinders.length; ++i) {
+ try {
+ var maybePlugin = pluginFinders[i]();
+ if (maybePlugin != null && maybePlugin.init(window)) {
+ plugin = maybePlugin;
+ break;
+ }
+ } catch (e) {
+ }
+ }
+ if (!plugin) {
+ // try searching for a v1 plugin for backwards compatibility
+ var found = false;
+ for (var i = 0; i < pluginFinders.length; ++i) {
+ try {
+ plugin = pluginFinders[i]();
+ if (plugin != null && plugin.connect($hosted, $moduleName,
window)) {
+ return;
+ }
+ } catch (e) {
+ }
+ }
+ loadIframe("http://gwt.google.com/missing-plugin");
+ } else {
+ if (plugin.connect(url, topWin.__gwt_SessionID, $hosted, $moduleName,
+ $hostedHtmlVersion)) {
+ window.onUnload = function() {
+ try {
+ // wrap in try/catch since plugins are not required to supply
this
+ plugin.disconnect();
+ } catch (e) {
+ }
+ };
+ } else {
+ if (errFn) {
+ errFn(modName);
+ } else {
+ alert("Plugin failed to connect to hosted mode server at " +
$hosted);
+
loadIframe("http://code.google.com/p/google-web-toolkit/wiki/TroubleshootingOOPHM");
+ }
+ }
+ }
+}
+
+window.onunload = function() {
+};
+
+// Lightweight metrics
+window.fireOnModuleLoadStart = function(className) {
+ $stats && $stats({moduleName:$moduleName, sessionId:$sessionId,
subSystem:'startup', evtGroup:'moduleStartup', millis:(new
Date()).getTime(), type:'onModuleLoadStart', className:className});
+};
+
+window.__gwt_module_id = 0;
+</script></head>
+<body>
+<font face='arial' size='-1'>This html file is for hosted mode
support.</font>
+<script><!--
+// Lightweight metrics
+$stats && $stats({moduleName:$moduleName, sessionId:$sessionId,
subSystem:'startup', evtGroup:'moduleStartup', millis:(new
Date()).getTime(), type:'moduleEvalEnd'});
+
+// OOPHM currently only supports IFrameLinker
+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>');
+}
+
+// look for the old query parameter if we don't find the new one
+var idx = query.indexOf("gwt.codesvr=");
+if (idx >= 0) {
+ idx += 12; // "gwt.codesvr=".length() == 12
+} else {
+ idx = query.indexOf("gwt.hosted=");
+ if (idx >= 0) {
+ idx += 11; // "gwt.hosted=".length() == 11
+ }
+}
+if (idx >= 0) {
+ var amp = query.indexOf("&", idx);
+ if (amp >= 0) {
+ $hosted = query.substring(idx, amp);
+ } else {
+ $hosted = query.substring(idx);
+ }
+
+ // According to RFC 3986, some of this component's characters (e.g., ':')
+ // are reserved and *may* be escaped.
+ $hosted = decodeURIComponent($hosted);
+}
+
+query = window.location.search.substring(1);
+if (query && $wnd[query]) setTimeout(function() {
$wnd[query].onScriptInstalled(gwtOnLoad) }, 1);
+--></script></body></html>
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/Linker.java Fri Jul 9
08:37:26 2010
+++ /trunk/dev/core/src/com/google/gwt/core/ext/Linker.java Wed Aug 18
11:12:36 2010
@@ -76,7 +76,7 @@
return false;
}
-
+
/**
* This method is invoked for linkers not annotated with {...@link
Shardable}. It
* sees all artifacts across the whole compile and can modify them
@@ -150,4 +150,12 @@
ArtifactSet newArtifacts) throws UnableToCompleteException {
return newArtifacts;
}
-}
+
+ /**
+ * Does this linker support DevMode?
+ */
+ public boolean supportsDevMode() {
+ // By default, linkers do not support Dev Mode
+ return false;
+ }
+}
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
Tue Jun 22 06:26:45 2010
+++
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
Wed Aug 18 11:12:36 2010
@@ -35,8 +35,10 @@
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -175,10 +177,16 @@
ArtifactSet toReturn = new ArtifactSet(artifacts);
toReturn.add(emitSelectionScript(logger, context, artifacts));
+ maybeAddHostedModeFile(logger, toReturn);
return toReturn;
}
}
+ @Override
+ public boolean supportsDevMode() {
+ return (getHostedFilename() != "");
+ }
+
protected Collection<Artifact<?>> doEmitCompilation(TreeLogger logger,
LinkerContext context, CompilationResult result)
throws UnableToCompleteException {
@@ -322,6 +330,7 @@
replaceAll(selectionScript, "__MODULE_FUNC__",
context.getModuleFunctionName());
replaceAll(selectionScript, "__MODULE_NAME__",
context.getModuleName());
+ replaceAll(selectionScript, "__HOSTED_FILENAME__",
getHostedFilename());
int startPos;
@@ -428,7 +437,7 @@
return selectionScript.toString();
}
-
+
/**
* Generate a Snippet of JavaScript to inject an external stylesheet.
*
@@ -460,6 +469,10 @@
protected abstract String getCompilationExtension(TreeLogger logger,
LinkerContext context) throws UnableToCompleteException;
+ protected String getHostedFilename() {
+ return "";
+ }
+
/**
* Compute the beginning of a JavaScript file that will hold the main
module
* implementation.
@@ -487,6 +500,50 @@
protected abstract String getSelectionScriptTemplate(TreeLogger logger,
LinkerContext context) throws UnableToCompleteException;
+
+ /**
+ * Add the hosted file to the artifact set.
+ */
+ protected void maybeAddHostedModeFile(TreeLogger logger, ArtifactSet
artifacts)
+ throws UnableToCompleteException {
+ String hostedFilename = getHostedFilename();
+ if ("".equals(hostedFilename)) {
+ return;
+ }
+ try {
+ URL resource =
SelectionScriptLinker.class.getResource(hostedFilename);
+ if (resource == null) {
+ logger.log(TreeLogger.ERROR,
+ "Unable to find support resource: " + hostedFilename);
+ throw new UnableToCompleteException();
+ }
+
+ final URLConnection connection = resource.openConnection();
+ // TODO: extract URLArtifact class?
+ EmittedArtifact hostedFile = new EmittedArtifact(
+ SelectionScriptLinker.class, hostedFilename) {
+ @Override
+ public InputStream getContents(TreeLogger logger)
+ throws UnableToCompleteException {
+ try {
+ return connection.getInputStream();
+ } catch (IOException e) {
+ logger.log(TreeLogger.ERROR, "Unable to copy support
resource", e);
+ throw new UnableToCompleteException();
+ }
+ }
+
+ @Override
+ public long getLastModified() {
+ return connection.getLastModified();
+ }
+ };
+ artifacts.add(hostedFile);
+ } catch (IOException e) {
+ logger.log(TreeLogger.ERROR, "Unable to copy support resource", e);
+ throw new UnableToCompleteException();
+ }
+ }
/**
* Find all instances of {...@link SelectionInformation} and add them to the
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
Tue Aug 10 07:06:57 2010
+++
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
Wed Aug 18 11:12:36 2010
@@ -84,6 +84,11 @@
return ".cache.js";
}
+ @Override
+ protected String getHostedFilename() {
+ return "hosted_xsiframe.html";
+ }
+
@Override
protected String getModulePrefix(TreeLogger logger, LinkerContext
context,
String strongName) {
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js
Tue Aug 10 07:06:57 2010
+++
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeTemplate.js
Wed Aug 18 11:12:36 2010
@@ -29,9 +29,6 @@
// The downloaded script code, once it arrives
,compiledScript
- // Whether the main script has been injected yet
- ,scriptInjected
-
// The iframe holding the app's code
,scriptFrame
@@ -83,8 +80,7 @@
try {
var query = $wnd.location.search;
return (query.indexOf('gwt.codesvr=') != -1
- || query.indexOf('gwt.hosted=') != -1
- || ($wnd.external && $wnd.external.gwtOnLoad)) &&
+ || query.indexOf('gwt.hosted=') != -1) &&
(query.indexOf('gwt.hybrid') == -1);
} catch (e) {
// Defensive: some versions of IE7 reportedly can throw an exception
@@ -94,14 +90,13 @@
return result;
}
- // Called when the body has been finished and when the script
- // to install is available. These can happen in either order.
- // When both have happened, create the code-holding iframe.
- //
+ // This function is called on two events: the body has finished
+ // loading, and the script to install is available. For hosted
+ // mode, install the hosted file as soon as the body is done.
+ // For prod mode, additionally wait until the script to install
+ // has been loaded, and then install the code.
function maybeCreateFrame() {
- if (bodyDone && compiledScript && !scriptInjected) {
- scriptInjected = true;
-
+ if (bodyDone && !scriptFrame && (isHostedMode() || compiledScript)) {
// Create the script frame, making sure it's invisible, but not
// "display:none", which keeps some browsers from running code in it.
scriptFrame = $doc.createElement('iframe');
@@ -114,7 +109,15 @@
// For some reason, adding this setTimeout makes code installation
// more reliable.
setTimeout(function() {
- installCode(compiledScript);
+ if (isHostedMode()) {
+ // TODO(unnurg) changing the src introduces cross-site
problems
+ // Neeed to add a hosted-xsiframe.js and install a script tag
+ // pointing at it
+ scriptFrame.contentWindow.location.replace(
+ base + "__HOSTED_FILENAME__?__MODULE_FUNC__");
+ } else {
+ installCode(compiledScript);
+ }
})
}
}
@@ -222,6 +225,9 @@
__MODULE_FUNC__.onScriptInstalled = function(gwtOnLoadFunc) {
// remove the callback to prevent it being called twice
__MODULE_FUNC__.onScriptInstalled = null;
+ if (isHostedMode()) {
+ scriptFrame.contentWindow.__gwt_getProperty = computePropValue;
+ }
gwtOnLoadFunc(onLoadErrorFunc, '__MODULE_NAME__', base,
softPermutationId);
// Record when the module EntryPoints return.
$stats && $stats({
@@ -240,12 +246,6 @@
// --------------- STRAIGHT-LINE CODE ---------------
- if (isHostedMode()) {
- alert("Cross-site hosted mode not yet implemented. See issue " +
- "http://code.google.com/p/google-web-toolkit/issues/detail?id=2079");
- return;
- }
-
// do it early for compile/browse rebasing
processMetas();
computeScriptBase();
@@ -262,20 +262,22 @@
});
var strongName;
- try {
+ if (!isHostedMode()) {
+ try {
// __PERMUTATIONS_BEGIN__
- // Permutation logic
+ // Permutation logic
// __PERMUTATIONS_END__
- var idx = strongName.indexOf(':');
- if (idx != -1) {
- softPermutationId = +(strongName.substring(idx + 1));
- strongName = strongName.substring(0, idx);
- }
- } catch (e) {
- // intentionally silent on property failure
- return;
- }
-
+ var idx = strongName.indexOf(':');
+ if (idx != -1) {
+ softPermutationId = +(strongName.substring(idx + 1));
+ strongName = strongName.substring(0, idx);
+ }
+ } catch (e) {
+ // intentionally silent on property failure
+ return;
+ }
+ }
+
var onBodyDoneTimerId;
function onBodyDone() {
if (!bodyDone) {
@@ -329,7 +331,6 @@
// __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
@@ -338,7 +339,10 @@
// 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 compiledScriptTag = '"<script src=\\"' + base + strongName
+ '.cache.js\\"></scr" + "ipt>"';
+ var compiledScriptWrite = '';
+ if (!isHostedMode()) {
+ compiledScriptWrite = 'document.write("<script src=\\"' + base +
strongName + '.cache.js\\"></scr" + "ipt>");';
+ }
$doc.write('<scr' + 'ipt><!-' + '-\n'
+ 'window.__gwtStatsEvent && window.__gwtStatsEvent({'
@@ -349,7 +353,7 @@
+ 'moduleName:"__MODULE_NAME__", sessionId:window.__gwtStatsSessionId,
subSystem:"startup",'
+ 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),'
+ 'type: "moduleRequested"});'
- + 'document.write(' + compiledScriptTag + ');'
+ + compiledScriptWrite
+ '\n-' + '-></scr' + 'ipt>');
}
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/linker/IFrameLinker.java Wed
Mar 31 06:57:50 2010
+++ /trunk/dev/core/src/com/google/gwt/core/linker/IFrameLinker.java Wed
Aug 18 11:12:36 2010
@@ -18,24 +18,17 @@
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
-import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
-import com.google.gwt.core.ext.linker.impl.HostedModeLinker;
import com.google.gwt.core.ext.linker.impl.SelectionScriptLinker;
import com.google.gwt.dev.About;
import com.google.gwt.dev.util.DefaultTextOutput;
import com.google.gwt.dev.util.Util;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
import java.util.SortedSet;
/**
@@ -116,54 +109,6 @@
public String getDescription() {
return "Standard";
}
-
- @Override
- public ArtifactSet link(TreeLogger logger, LinkerContext context,
- ArtifactSet artifacts, boolean onePerm) throws
UnableToCompleteException {
- ArtifactSet toReturn = super.link(logger, context, artifacts, onePerm);
-
- if (onePerm) {
- return toReturn;
- }
-
- try {
- // Add hosted mode iframe contents
- // TODO move this into own impl package if HostedModeLinker goes away
- URL resource = HostedModeLinker.class.getResource("hosted.html");
- if (resource == null) {
- logger.log(TreeLogger.ERROR,
- "Unable to find support resource 'hosted.html'");
- throw new UnableToCompleteException();
- }
-
- final URLConnection connection = resource.openConnection();
- // TODO: extract URLArtifact class?
- EmittedArtifact hostedHtml = new EmittedArtifact(IFrameLinker.class,
- "hosted.html") {
- @Override
- public InputStream getContents(TreeLogger logger)
- throws UnableToCompleteException {
- try {
- return connection.getInputStream();
- } catch (IOException e) {
- logger.log(TreeLogger.ERROR, "Unable to copy support
resource", e);
- throw new UnableToCompleteException();
- }
- }
-
- @Override
- public long getLastModified() {
- return connection.getLastModified();
- }
- };
- toReturn.add(hostedHtml);
- } catch (IOException e) {
- logger.log(TreeLogger.ERROR, "Unable to copy support resource", e);
- throw new UnableToCompleteException();
- }
-
- return toReturn;
- }
/*
* This implementation divides the code of the initial fragment into
multiple
@@ -184,7 +129,7 @@
b.append(getModuleSuffix(logger, context));
return Util.getBytes(b.toString());
}
-
+
@Override
protected String getCompilationExtension(TreeLogger logger,
LinkerContext context) {
@@ -214,6 +159,11 @@
return subdir;
}
+
+ @Override
+ protected String getHostedFilename() {
+ return "hosted.html";
+ }
@Override
protected String getModulePrefix(TreeLogger logger, LinkerContext
context,
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js Thu
Mar 25 12:00:47 2010
+++ /trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js Wed
Aug 18 11:12:36 2010
@@ -249,7 +249,7 @@
$wnd.location.reload();
return;
}
- initialHtml = "hosted.html?__MODULE_FUNC__";
+ initialHtml = "__HOSTED_FILENAME__?__MODULE_FUNC__";
strongName = "";
}
=======================================
--- /trunk/user/src/com/google/gwt/junit/JUnitShell.java Thu Aug 12
07:56:03 2010
+++ /trunk/user/src/com/google/gwt/junit/JUnitShell.java Wed Aug 18
11:12:36 2010
@@ -1092,10 +1092,16 @@
}
}
if (developmentMode) {
- // BACKWARDS COMPATIBILITY: most linkers currently fail in dev mode.
- if (module.getLinker("std") != null) {
- // TODO: unfortunately, this could be race condition between
dev/prod
- module.addLinker("std");
+ // BACKWARDS COMPATIBILITY: many linkers currently fail in dev mode.
+ try {
+ if
(!module.getActivePrimaryLinker().newInstance().supportsDevMode()) {
+ if (module.getLinker("std") != null) {
+ // TODO: unfortunately, this could be race condition between
dev/prod
+ module.addLinker("std");
+ }
+ }
+ } catch (Exception e) {
+ getTopLogger().log(TreeLogger.WARN, "Failed to instantiate
linker: " + e);
}
super.link(getTopLogger(), module);
} else {
=======================================
---
/trunk/user/test/com/google/gwt/core/ext/test/CrossSiteIframeLinkerTest.java
Tue Aug 10 07:06:57 2010
+++
/trunk/user/test/com/google/gwt/core/ext/test/CrossSiteIframeLinkerTest.java
Wed Aug 18 11:12:36 2010
@@ -16,13 +16,10 @@
package com.google.gwt.core.ext.test;
-import com.google.gwt.junit.DoNotRunWith;
-import com.google.gwt.junit.Platform;
/**
* Integration test of the cross-site iframe linker.
*/
-...@donotrunwith(Platform.Devel)
public class CrossSiteIframeLinkerTest extends LinkerTest {
@Override
public String getModuleName() {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors