Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

body.onload and GWT onModuleLoad launch order

According to this FAQ, when GWT bootstraps, onModuleLoad is supossed to run before HTML body's onload event. The process detailed within that FAQ works like this:

1. The HTML document is fetched and parsing begins.
...
9. externalScriptOne.js completes. The document is ready, so onModuleLoad() fires.
...
12. body.onload() fires, in this case showing an alert() box.

But in my tests, i have checked that it doesnt work this way. Or at least not in every browser (oddly, Google Chrome in particular doesn't stick to this kind of behaviour). For example, I have this little test involving onModuleLoad and body.onLoad:

public void onModuleLoad() {

    runTestFunction();

}

private native void runTestFunction() /*-{
    console.log("GWT's onModuleLoad");
    $wnd.loaded=true;
}-*/;

And:

<body onload="console.log('body.onLoad');if(loaded!=null) console.log('loaded var is set');">

If i launch firefox, and run this example, the console will show this:

GWT's onModuleLoad
body.onLoad
loaded var is set

But in Chrome:

body.onLoad
Uncaught ReferenceError: loaded is not defined
GWT's onModuleLoad

In the latter, onModuleLoad runs the last, thus "loaded" var is not yet available and body.onLoad code cant use it.

And what Im trying to achieve? I want some handwritten Javascript that runs within body.onload to interact with my GWT code. In this example i use this dummy "loaded" var, but in the future it should be able to call GWT functions written in Java. The problem is that i need to make sure that onModuleLoad runs first so it can export the variables and methods for javascript to access them.

So, what am i missing? Is this behaviour as unreliable as it looks like, or am i doing something wrong?

PS: i have a plan B to achieve this which is proved to work, but first i want to make sure that it isnt possible to do it this way since this should be the preferred method.

like image 315
Kilian Perdomo Curbelo Avatar asked Nov 28 '25 13:11

Kilian Perdomo Curbelo


1 Answers

First, the latest version of the doc is at http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideBootstrap

And it says (even the GWT 1.5 version you were looking at) that "onModuleLoad() can be called at any point after the outer document has been parsed", which includes before and after window.onload.

As the doc says, GWT loads your code in an iframe (used here as a sandbox), which is asynchronous; so your code loads when both the iframe and the "body" are loaded. Depending on the time needed to load the iframe, that can be before or after window.onload (in the example, they assume it loads right away, which could be the case when the *.cache.* file is effectively in the browser's cache).

But the rule of thumb is that GWT tries hard (at least the built-in linkers) to make things start asynchronously so that it doesn't break loading of other external resources (stylesheets and images, for instance). That implies that it cannot be guaranteed to run before the window.onload (they could have guaranteed to run after window.onload, but why wait?)

like image 57
Thomas Broyer Avatar answered Nov 30 '25 06:11

Thomas Broyer