5

I'm writing an app in GWT (mapfaire.com) which uses the Google Maps API, and I'd like to use the utilities library. Writing a JSNI wrapper for the libraries isn't a problem, but how do I ensure the compiler 'bakes' the JS into the app itself, rather than downloading them separately via a module script include?

Sudhir Jonathan
  • 16,998
  • 13
  • 66
  • 90

4 Answers4

8

You could define a ClientBundle for your JavaScript resources like this:

public interface JsResources extends ClientBundle {
    final JsResources INSTANCE = GWT.create(JsResources.class);

    @Source("myAwesomeJavaScript.js")
    TextResource myAwesomeJavaScript();
}

and include it in your app with the ScriptInjector:

ScriptInjector
    .fromString( JsResources.INSTANCE.myAwesomeJavaScript().getText() )
    .inject();
Dennis
  • 1,805
  • 14
  • 17
  • 3
    imo this is the best solution, bundling the js into a textresource will reduce an additional http request to load the js. – Ali May 12 '14 at 07:14
6

In gwt 2.4 added ScriptInjector http://gwt-code-reviews.appspot.com/1451818/

   ScriptInjector.fromUrl("http://example.com/foo.js").setCallback(
     new Callback<Void, Exception>() {
        public void onFailure(Exception reason) {
          Window.alert("Script load failed.");
        }
        public void onSuccess(Void result) {
          Window.alert("Script load success.");
        }
     }).inject();
Helpa
  • 709
  • 1
  • 12
  • 23
2

If the license allows you to do so, then you could copy and paste the entire JS code of the library into a JSNI method.

You can also use a TextResource like this:

public static interface Resources extends ClientBundle {
    @Source("some.js")
    TextResource someJs();
}

public void onModuleLoad() {
    final Resources resources = GWT.create(Resources.class);
    eval(resources.someJs().getText());
}

private static native void eval(String s) /*-{
    eval(s);
}-*/;

The text of "some.js" will be interned directly into the resulting application. There won't be any separate download.

Chris Lercher
  • 37,264
  • 20
  • 99
  • 131
  • Yeah, I could, but I really want something cleaner. And I might have the files moved in during the build as a dependency. – Sudhir Jonathan Nov 20 '10 at 17:45
  • @Sudhir: I fully understand that. However, gwtc is just a Java to JavaScript compiler/converter, which can additionally include JavaScript by JSNI. So I don't see a direct way. Maybe you can construct an indirect solution like this: Include the JS code as a TextResource (ClientBundle), then eval the text in JSNI. Haven't tried this yet! – Chris Lercher Nov 20 '10 at 18:04
  • Right now, it can mark a js file as a script resource, and ensure it's downloaded before the module is run. I'm trying to see if anyone knows a way by which I can tell GWT to put this file into the module itself. It would still do exactly the same thing, with fewer requests. – Sudhir Jonathan Nov 20 '10 at 18:15
  • @Sudhir: I gave the TextResource idea a quick try (see updated answer). It works, and the result is, that you actually do get fewer requests. BTW, how do you mark a js file as a "script resource", sounds interesting? – Chris Lercher Nov 21 '10 at 08:26
  • @Chris http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideAutomaticResourceInclusion talks about it... just add a script tag in the module file. GWT will ensure that this script is downloaded before the module is run. This can either be external js (google maps?) or internal, like now. Page execution waits for this request to finish, though, which is an unnecessary bottleneck. – Sudhir Jonathan Nov 22 '10 at 03:09
  • Thanks for the Resource tip... that's probably what I'll go with eventually. – Sudhir Jonathan Nov 22 '10 at 03:10
  • Works great, except that `$wnd` will have to be added all over the script to scope it correctly, especially if you're including a maps plugin like I am. – Sudhir Jonathan Nov 28 '10 at 07:36
0

Is the gwt-maps-utility project useful for your needs?

z00bs
  • 7,518
  • 4
  • 34
  • 53