Search code examples
javascriptgwtbookmarklet

GWT bookmarket or GWT as an external library


I simply want to load a GWT(Google Web Toolkit) app by adding a script tag to the DOM, however because the GWT linker uses document.write() I'm unable to find any good way of doing so. I've found some hacks for doing so on various blog posts but they all seem to fail with the latest version of GWT. Any reasonably non-invasive approach for doing this come to mind?

Clarification:

Normal way to start up a GWT app, in your host html page:

<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script> 

This, of course, starts up as soon as the page loads. I want to do it at a later time:

function startapp() {
    var head = document.getElementsByTagName('head');
    var s = document.createElement('script');
    s.setAttribute('type', 'text/javascript');
    s.setAttribute('src', 'myapp.nocache.js');
    head[0].appendChild(s);
}

Solution

  • Here's what seems to work so far:

    Add this to the top of your App.gwt.xml:

    <!-- Cross site linker -->
    <inherits name="com.google.gwt.core.Core" />
    <add-linker name="xs" />
    

    After compiling your app with the above setting, modify (or copy) the generated app.nocache.js as follows:

    1) Comment the last $doc.write... statement

    2) Copy this portion from the $doc.write statement you just commented out and eval it. Example:

    eval('window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),' + 'type: "end"});' + 'window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),' + 'type: "moduleRequested"});');
    

    3) Add this line right after.

    document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js";
    

    So you're basically replacing the $doc.write with those two lines.

    Now, your bookmarklet will look something like:

    <a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a>