@Retention(value=RUNTIME) @Target(value=METHOD) public @interface JSBody
Indicates that method is to have native JavaScript implementation.
Method only can take and return primitive values and JSObject
s.
Note that unless method is static, it must belong to class that implements JSObject
.
If applied to non-native method, original Java body will be overwritten by JavaScript.
Example:
@JSBody(params = { "message" }, script = "window.alert(message);") public static native void alert(String message);
The motivation for params
field is the following: Java can avoid inclusion of parameter names
into bytecode (for example, you can compile with no debug information). In order the JSO implementation
with no access to original source code could work properly, JSO forces developer to specify parameter
names explicitly.
A method marked with JSBody annotation is restricted to take parameters of allowed types. A type is allowed if it is either:
boolean
, byte
, short
, char
,
int
, long
, float
or double
;java.lang.String
class;JSObject
;Java primitives are converted to corresponding JavaScript primitives, except for char
,
which does not have corresponding JavaScript representation. JSO implementation converts Java chars to JavaScript
numbers, and expects a JavaScript number when converting to a Java character.
Java arrays are converted to JavaScript arrays and vice versa. Arrays are passed by copy.
java.lang.String
objects are converted to JavaScript string.
Overlay types are passed as is.
Sometimes JavaScript functions expect you to pass a function as a parameter value. JSO allows you to
pass special form of overlay objects as functions. These overlay objects must be interfaces with exactly one
parameter and marked with JSFunctor
annotation. Example:
@JSFunctor interface TimerHandler extends JSObject { void onTimer(); } @JSBody(params = { "handler", "delay" }, script = "return window.setTimeout(handler, delay);") public static native int setTimeout(TimerHandler handler, int delay);
You can call Java methods from JSBody script. You should use the following notation:
javaMethods.get('method reference').invoke([instance, ] param1 [, param2 ...]);
The method reference has the following format:
(PackageName .)* ClassName . MethodName MethodDescriptor
where
PackageName = Identifier ClassName = Identifier MethodName = Identifier MethodDescriptor = ( TypeDescriptor ) V) | ( TypeDescriptor ) TypeDescriptor TypeDescriptor = Z | B | C | S | I | J | F | D | L QualifiedClassName ; | [ TypeDescriptor.
that is similar to method descriptors augmented with class and method names.
For example,
@JSBody(params = { "message" }, script = "javaMethods.get('org.teavm.jso.browser.Window" + ".alert(Ljava/lang/String;)V').invoke(message);") public static native void alertCaller(String message);
Note that get
method must take string constant. Dynamic resolution of Java methods may
not work on some platforms.
JSObject
Copyright © 2017. All rights reserved.