JavaScript Native Interface Scott Blum GWT...
Transcript of JavaScript Native Interface Scott Blum GWT...
![Page 1: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/1.jpg)
JavaScript Native Interface
Scott Blum
GWT Engineer
![Page 2: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/2.jpg)
JavaScript Native Interface (JSNI)
• What is JSNI?
• Them be the rules
• JavaScriptObject
• Practical JSNI
• Discussion
![Page 3: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/3.jpg)
Handwritten JavaScript in Java
public class Hello implements EntryPoint {
native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
public void onModuleLoad() {
alert("Hello World!");
}
}
![Page 4: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/4.jpg)
Abusing Java syntax :)
native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
![Page 5: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/5.jpg)
Abusing Java syntax :)
native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
![Page 6: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/6.jpg)
Abusing Java syntax :)
native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
![Page 7: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/7.jpg)
Use Browser APIs Directly
public class Hello implements EntryPoint {
native void inject(String url) /*-{
var script = $doc.createElement("script");
script.src = url;
$doc.body.appendChild(script);
}-*/;
public void onModuleLoad() {
inject("foo.js");
}
}
![Page 8: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/8.jpg)
Actually, that was a contrived example
void inject(String url) {
Element script = DOM.createElement("script");
DOM.setElementProperty(script, "src", url);
DOM.appendChild(RootPanel.get().getElement(),
script);
}
![Page 9: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/9.jpg)
Actually, that was a contrived example
void inject(String url) {
Element script = DOM.createElement("script");
DOM.setElementProperty(script, "src", url);
DOM.appendChild(RootPanel.get().getElement(),
script);
}
But how does GWT implement this…?
![Page 10: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/10.jpg)
GWT core libraries are built on JSNI
native Element createElement(String tag) /*-{
return $doc.createElement(tag);
}-*/;
native void setElementProperty(Element elem,
String prop, String value) /*-{
elem[prop] = value;
}-*/;
native void appendChild(Element parent,
Element child) /*-{
parent.appendChild(child);
}-*/;
![Page 11: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/11.jpg)
Perhaps in the future…
void inject(String url) {
ScriptElement script = ScriptElement.create();
script.setSrc(url);
Body.get().appendChild(script);
}
![Page 12: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/12.jpg)
char[] to String, Java
String valueOf(char[] in) {
String result = "";
for (int i = 0; i < in.length; ++i) {
result += in[i];
}
return result;
}
![Page 13: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/13.jpg)
char[] to String, JavaScript
native String valueOf(char[] x) /*-{
// Trick: fromCharCode is a vararg method;
// Use apply() to pass the input in one shot.
return String.fromCharCode.apply(null, x);
}-*/;
![Page 14: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/14.jpg)
Concat vs. native, char[] to String
� concat
16k char ~2000ms
Appears ~O(n2)
� native
500k char ~300ms
Appears ~O(n)
![Page 15: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/15.jpg)
JavaScript Native Interface (JSNI)
• What is JSNI?
• Them be the rules
• JavaScriptObject
• Practical JSNI
• Discussion
![Page 16: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/16.jpg)
Passing values
ObjectJavaScriptObject
Opaque objectObject
Boolean primitiveboolean
String object or primitiveString
Numeric primitiveint, byte, short, double, etc…
JavaScript typeDeclared Java Type
![Page 17: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/17.jpg)
Passing values
native int getNumber() /*-{
return "2";
}-*/;
public void onModuleLoad() {
int x = getNumber();
Window.alert(x + x);
}
![Page 18: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/18.jpg)
Passing values, surprising results
native int getNumber() /*-{
return "2";
}-*/;
public void onModuleLoad() {
int x = getNumber();
Window.alert(x + x); // "22" in web mode
}
![Page 19: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/19.jpg)
Passing values, hosted mode checks
native int getNumber() /*-{
return "2";
}-*/;
public void onModuleLoad() {
int x = getNumber(); // HostedModeException
Window.alert(x + x);
}
![Page 20: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/20.jpg)
Value passing, hosted vs. web mode
JVM bytecode
JSNI method
JVM bytecode
GLUE
return
return
args
args
JavaScript
return
return
args
args
JavaScript
JavaScript
GLUE
GLUE
GLUE
![Page 21: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/21.jpg)
Java Objects in JSNI, fields
public class ArrayList<E> extends AbstractList<E>{
…
private JavaScriptObject array;
private native E getImpl(int index) /*-{
return [email protected]::array[index];
}-*/;
…
}
![Page 22: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/22.jpg)
Java Objects in JSNI, methods
native void addAllKeys(Set<String> s,
JavaScriptObject jso) /*-{
for (var key in jso) {
[email protected]::add(Ljava/lang/Object;)(key);
}
}-*/;
![Page 23: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/23.jpg)
Java Objects in JSNI, statics
final class XMLHTTPRequest {
public static final int LOADED = 4;
static native String send(JSO xhr, …) /*-{
xhr.onreadystatechange = function() {
if (xmlHttpRequest.readyState ==
@package.XMLHTTPRequest::LOADED) {
// do stuff
}
}-*/;
}
![Page 24: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/24.jpg)
Accessing the window and document
HTML Page
GWT
code
HTML Page
GWT code
Normal: runs in an
IFRAME
Mashup: runs in an
anonymous function
body
![Page 25: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/25.jpg)
Accessing the window and document
native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
native Element createElement(String tag) /*-{
return $doc.createElement(tag);
}-*/;
![Page 26: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/26.jpg)
JavaScript Exceptions
native void throwException() /*-{
var x; x.foo();
}-*/;
public void onModuleLoad() {
try {
throwException();
} catch (Throwable e) {
// What is e?
Window.alert(e.getClass.getName());
}
}
![Page 27: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/27.jpg)
JavaScript Exceptions
native void throwException() /*-{
var x; x.foo();
}-*/;
public void onModuleLoad() {
try {
throwException();
} catch (Throwable e) {
// com.google.gwt.core.client.JavaScriptException
Window.alert(e.getClass.getName());
}
}
![Page 28: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/28.jpg)
Exception Sandwich
native void sandwich() /*-{try {@package.Hello::throwMyException()();} catch (e) {throw e; // may not hold identity in hosted mode}}-*/;public void onModuleLoad() {try {sandwich();} catch (MyException e) {Window.alert(e.toString()); // identity retained}}
![Page 29: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/29.jpg)
undefined vs. null
native String getString() /*-{}-*/;
public void onModuleLoad() {String s = getString();if (s != null) {Window.alert(s);}}
![Page 30: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/30.jpg)
undefined vs. null
native String getString() /*-{// implicitly returns undefined}-*/;
public void onModuleLoad() {String s = getString();if (s != null) {Window.alert(s); // web mode: alerts "undefined"!}}
![Page 31: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/31.jpg)
undefined vs. null
function getString() {// implicitly returns undefined}
function onModuleLoad() {var s = getString();if (s !== null) {// undefined !== null; execution reaches here$wnd.alert(s);
}}
![Page 32: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/32.jpg)
undefined vs. null
undefined == null => trueundefined != null => falseundefined === null => falseundefined !== null => true
![Page 33: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/33.jpg)
undefined vs. null
undefined == null => trueundefined != null => falseundefined === null => falseundefined !== null => true
Then why not generate “==” tests?
![Page 34: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/34.jpg)
undefined vs. null
undefined == null => trueundefined != null => falseundefined === null => falseundefined !== null => true
Then why not generate “==” tests?
var o = new Object();o == "[object Object]" => true(!)o === "[object Object]" => falseo == new String("[object Object]") => false(!!)o === new String("[object Object]") => false
![Page 35: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/35.jpg)
JavaScript identity, pick two
• Triple equals identity testing
• String primitive and object interchangeable
• undefined and null interchangeable
![Page 36: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/36.jpg)
Never return undefined
native String getElementProperty(Element elem,String prop) /*-{var ret = elem[prop];return (ret == null) ? null : ret;}-*/;
![Page 37: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/37.jpg)
Never return undefined
native String getString() /*-{}-*/;
public void onModuleLoad() {String s = getString(); // HostedModeExceptionif (s != null) {Window.alert(s);}}
![Page 38: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/38.jpg)
JavaScript Native Interface (JSNI)
• What is JSNI?
• Them be the rules
• JavaScriptObject
• Practical JSNI
• Discussion
![Page 39: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/39.jpg)
JavaScriptObject
public class Button {
static native Element createButton() /*-{
return $doc.createElement("button");
}-*/;
private Element element = createButton();
…
}
![Page 40: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/40.jpg)
JavaScriptObject
com.google.gwt.core.client.JavaScriptObject
An opaque handle to a native JavaScript
object. A JavaScriptObject cannot be created
directly. JavaScriptObject should be
declared as the return type of a JSNI method
that returns native (non-Java) objects. A
JavaScriptObject passed back into JSNI from
Java becomes the original object, and can be
accessed in JavaScript as expected.
SUBCLASSING IS NOT SUPPORTED EXCEPT FOR
EXISTING SUBCLASSES.
![Page 41: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/41.jpg)
JavaScriptObject
Object
JavaScriptObject
Element Event
![Page 42: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/42.jpg)
JavaScriptObject
Object
JavaScriptObject
Element Event
�MAGIC
![Page 43: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/43.jpg)
JavaScriptObject and virtual dispatch
public final class Element extends JavaScriptObject {
public String toString() {
return DOM.toString(this); // innerHTML
}
}
public void onModuleLoad() {
Element e = DOM.createButton();
e.toString();
alert(e instanceof Element);
}
![Page 44: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/44.jpg)
JavaScriptObject and virtual dispatch
public final class Element extends JavaScriptObject {
public String toString() {
return DOM.toString(this); // innerHTML
}
}
public void onModuleLoad() {
Element e = DOM.createButton();
Object o = rnd() ? this : e;
o.toString();
alert(o instanceof Element);
}
![Page 45: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/45.jpg)
JavaScriptObject decoration
public final class Element extends JavaScriptObject {
public String toString() {
return DOM.toString(this); // innerHTML
}
}
public void onModuleLoad() {
Element e = wrap(DOM.createButton(), Element.class);
Object o = rnd() ? this : e;
o.toString();
alert(o instanceof Element);
}
![Page 46: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/46.jpg)
JavaScriptObject and implicit upcast
public final class Element extends JavaScriptObject {
public String toString() {
return DOM.toString(this); // innerHTML
}
}
public void onModuleLoad() {
Element e = DOM.createButton();
Object o = rnd() ? this : wrap(e, Element.class);
o.toString();
alert(o instanceof Element);
}
![Page 47: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/47.jpg)
JavaScriptObject
• Can be zero-overhead
• The rules are still changing
• Native instance methods supported in 1.5
• Use final instance methods
• Avoid implicit upcasts
![Page 48: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/48.jpg)
JavaScript Native Interface (JSNI)
• What is JSNI?
• Them be the rules
• JavaScriptObject
• Practical JSNI
• Discussion
![Page 49: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/49.jpg)
Where does GWT use it?
• JRE emulation (String, ArrayList, HashMap)
• DOM manipulation
• History
• XMLHttpRequest
• Timer / DeferredCommand
• JSON library
![Page 50: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/50.jpg)
RPC field serialization
public class Person implements IsSerializable {
private String description;
private String name;
…
}
public class Person_FieldSerializer {
String getDescription(Person instance) {
return instance.description; // Compile error
}
…
}
![Page 51: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/51.jpg)
The Violator Pattern
public class Person implements IsSerializable {
private String description;
private String name;
…
}
public class Person_FieldSerializer {
native String getDescription(Person instance) /*-{
return [email protected]::description;
}-*/;
…
}
![Page 52: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/52.jpg)
JSON Parsing
{ name: "doglover",
url: "http://flickr.com/people/doglover/",
images: [
{ title: "Rover",
url: "http://flickr.com/photos/doglover/12345/",
width: 300,
height: 200 },
… ]
}
![Page 53: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/53.jpg)
JSON Parsing
class Album extends JavaScriptObject {
native String getName() /*-{ return this.name; }-*/;
native String getUrl() /*-{ return this.url; }-*/;
native int getImageCount() /*-{
return this.images.length;
}-*/;
native Image getImage(int index) /*-{
return this.images[index];
}-*/;
}
![Page 54: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/54.jpg)
JSON Parsing
class Image extends JavaScriptObject {
native String getTitle() /*-{ return this.title; }-*/;
native String getUrl() /*-{ return this.url; }-*/;
native int getWidth() /*-{ return this.width; }-*/;
native int getHeight() /*-{ return this.height; }-*/;
}
![Page 55: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/55.jpg)
…and beyond!
class Image extends JavaScriptObject {
native void show(Element parent, int w, int h) /*-{
this.show(parent, w, h);
}-*/;
}
![Page 56: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/56.jpg)
Beyond beyond
class Image extends JavaScriptObject {
interface ImageEvents {
void onFadeIn(Image sender);
}
native void fadeIn(ImageEvents evts) /*-{
var img = this;
this.fadeIn(function() {
[email protected]::onFadeIn(Lpkg/Image;)(img);
});
}-*/;
}
![Page 57: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/57.jpg)
Appropriate use of JSNI
• Prefer to use Java
• Write smaller “leaf” methods and keep complex logic in Java
• Use JS->Java references sparingly
• In GWT 1.5, simple JSNI methods are inlined
• JavaScriptObject is still evolving
![Page 58: JavaScript Native Interface Scott Blum GWT Engineerptgmedia.pearsoncmg.com/imprint_downloads/voices...An opaque handle to a native JavaScript object. A JavaScriptObject cannot be created](https://reader033.fdocuments.us/reader033/viewer/2022043011/5fa77c2637434f09214a23d4/html5/thumbnails/58.jpg)
Resources
• GWT documentationhttp://code.google.com/webtoolkit/documentation
• GWT source codehttp://code.google.com/p/google-web-toolkit/
• JavaScript InterOp Library (JSIO)http://code.google.com/p/gwt-api-interop/
Discussion?