JsInterop Deep Drive

Arnaud Tournier, le 11-11-2015

Speaker : Julien Dramaix

Why do we need JsInterop ?

10 years ago, JS ecosystem was poor.

So GWT was used as an abstraction layer above javascript differences.

Now JS ecosystem rocks. We wat to tak advantage from these libraries.

Options were : (re)writing a library in Java, wrap with JSNI, …

So need a better system to interoperate with JS.

JsInterop is two-way (JS to Java and Java to JS).

Specifications

Enabled by default.

If you want to export java types to javascript : -generateJsInteropExports true.

JsType

Exposing your Java definition to the Javascript world.

package com.foo;

@JsType
public class Bar {
	public boolean b = true;
}



var bar = new com.foo.Bar();
bar.b = false;

JsType is not inherited.

A jstype cannot have methodes/propertyes with same name as Javascriptname

Only one @JsContructor

GWT doesn’t support method overloading for JsType (becasue JS does not)

@JsIgnore allow to ignore on field or method when using @JsType

Native JsType

@JsType(isNative = true)
public abstract class JQuery {
	@JsMethod(namespace=GLOBAL)
	public native static JQuery $(String selector);

	public native JQuery css(String prop, String val);
	public native JQuery attr(String name, String val);
}

It is possible to extend or implement JsTypes.

JsOverlayMethods

@JsType(isnative=true)
classs FancyWidget{
	public native boolean isVisible();
	... setVisible

	@JsOverlay
	public final void toggle() {
		setVisible(!isVisible);
	}
}

JsProperty, JsMethod, JsConstructor

JsType is equivalent to :

class Bar {
	@JsProperty

	@JsConstructor

	@JsMethod
}

@JsProperty can be used on methods. Useful to make Fluent API

Be careful @JsMethod and @JsProperty and @JsType act as entry point of your application, so the GWT compiler will not prune them. So be careful !!

JsFunctioic int action

@JsType(isNative=true)
interface Promise {
	Promise success(PromiseCallback callback);
}

@JsFunction
@FunctionalInterface
interface PromiseCallback {
	void execute();
}

It also works the other way around ()

JsType : name and namespace

name change the name, namespace changes the package.

Sample : how to declare array

@JsType(native, namespace=GLOBAL, name="Array")
class JsArray<T>{
	public native void push(T item);
}

public class Foo {
	@JsMethod native static void log(String message);
}

public class Foo {
	@JsProperty(namespace=GLOBAL)
	public native static Angular getAngular();
}

JsPackage

package-info.java

@jsinterop.annotations.JsPackage(namespace="acme")

Example : an AngularJs application with GWT

Julian shows how to convert the Todolist sample in the ANgular JS website to a full GWT application.

Clear, simple and easy, perfect !

Just one hickup :

Todo class is non native @JsType. But sometimes we receive instances from JS which are not Todo but json objects with same fields. Solution is to declare a TodoDTO type as a native @JsType and convert to Todo

github.com/jDramaix/AngularGwtExample

Questions

Tool to know all the JsEntrypoints ? In order to see we didn’t @JsExport something by mistake…

Not yet…


Arnaud Tournier, le 11-11-2015