All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.javascript.JavascriptContext Maven / Gradle / Ivy

There is a newer version: 7.0.161
Show newest version
/*
 * Copyright (c) 2012, Steve Hannah/Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */
package com.codename1.javascript;

import com.codename1.io.Log;
import com.codename1.io.Util;
import com.codename1.ui.BrowserComponent;
import com.codename1.ui.Display;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.events.BrowserNavigationCallback;
import com.codename1.util.Callback;
import com.codename1.util.CallbackAdapter;
import com.codename1.util.StringUtil;
import com.codename1.util.SuccessCallback;
import java.util.Hashtable;
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Random;

/**
 * Represents a Javascript context of a single BrowserComponent.  This provides
 * support for executing Javascript in the BrowserComponent, registering Java
 * callbacks to allow Javascript to call Java functions, and returning values
 * from Javascript to Java.
 * 
 * 

* NOTE: The {@link com.codename1.javascript } package is now * deprecated. The preferred method of Java/Javascript interop is to use {@link BrowserComponent#execute(java.lang.String) }, {@link BrowserComponent#execute(java.lang.String, com.codename1.util.SuccessCallback) }, * {@link BrowserComponent#executeAndWait(java.lang.String) }, etc.. as these * work asynchronously (except in the XXXAndWait() variants, which use * invokeAndBlock() to make the calls synchronously.

* *

* Typically you would obtain a context for a BrowserComponent via its constructor, * passing the BrowserComponent to the context.

*

E.g.

*
 * WebBrowser b = new WebBrowser();
 * BrowserComponent bc = (BrowserComponent)b.getInternal();
 * JavascriptContext ctx = new JavascriptContext(bc);
 * JSObject window = (JSObject)ctx.get("window");
 * 
* * @author shannah * @deprecated Use {@link BrowserComponent#execute(java.lang.String) } directly. */ public class JavascriptContext { private int callbackId=0; /** * Flag to enable/disable logging to a debug log. */ public static boolean DEBUG=false; /** * The browser component on which this context operates. * @see setBrowserComponent() * @see getBrowserComponent() */ BrowserComponent browser; /** * Listener that listens for JavascriptEvents. A Javascript event * is packaged by the JavascriptContext class in response to a * BrowserNavigationCallback. */ private ActionListener scriptMessageListener; /** * A handler for navigation attempts. This intercepts URLs of the * form cn1command:... . This is how Javascript communicates/calls * methods in this context. */ private BrowserNavigationCallback browserNavigationCallback; /** * Stores the previous BrowserNavigationCallback object if one * was registered on the BrowserComponent. */ private BrowserNavigationCallback previousNavigationCallback; /** * The name of the Javascript lookup table that is used to store and * look up Javascript objects that have a JSObject proxy. */ String jsLookupTable; /** * A running counter for the next object ID that is to be assigned to * the next JSObject. Each JSObject has an id associated with it which * corresponds with its position in the Javascript lookup table. */ int objectId = 0; /** * Stores registered JSFunction callbacks which can be called in response * to a JavascriptEvent. */ private Hashtable callbacks = new Hashtable(); /** * Running counter to mark the context ID. Each javascript context has its * own lookup table, and this running counter allows us to generate a unique * name for each lookup table. */ private static int contextId = 0; /** * A dummy javascript variable that is used occasionally to workaround some bugs. */ static final String DUMMY_VAR = "ca_weblite_codename1_js_JavascriptContext_DUMMY_VAR"; /** * Javascript variable to store the return value of get() requests so that the value can be * returned. */ static final String RETURN_VAR = "ca_weblite_codename1_js_JavascriptContext_RETURN_VAR"; /** * The base name of the lookup table. The actual name of the lookup table will have the * contextId appended to it, and be stored as the member variable jsLookupTable. */ static final String LOOKUP_TABLE = "ca_weblite_codename1_js_JavascriptContext_LOOKUP_TABLE"; /** * A map of JSObjects that is used for cleanup when they are no longer needed. */ private HashMap objectMap = new HashMap(); /** * Whenever the objectMap exceeds this size, cleanup will be called whenever retain() * is called. */ private int objectMapThresholdSize = 500; private Random cleanupRandomizer = new Random(); private double cleanupProbability = 0.1; private JSObject window; /** * Creates a Javascript context for the given BrowserComponent. * @param c */ public JavascriptContext(BrowserComponent c){ jsLookupTable = LOOKUP_TABLE+(contextId++); this.browserNavigationCallback = new NavigationCallback(); this.scriptMessageListener = new ScriptMessageListener(); this.setBrowserComponent(c); } /** * Sets the BrowserComponent on which this javascript context runs. * * @param c The BrowserComponent on which the context runs. */ public final void setBrowserComponent(BrowserComponent c){ if ( c != browser ){ if ( browser != null ){ this.uninstall(); } browser = c; if ( browser != null ){ this.install(); } } } /** * Increments the reference count for a the javascript object wrapped by * the given JSObject. This may also trigger a cleanup of the object map if * the map grows too big, or it randomly decided to perform cleanup. * @param obj */ void retain(JSObject obj){ objectMap.put(new Integer(obj.objectId), Display.getInstance().createSoftWeakRef(obj)); if ( objectMap.size() > objectMapThresholdSize || cleanupRandomizer.nextDouble() < cleanupProbability ){ cleanup(); } } /** * Decrements the reference count for the javascript object with the given id. * This ID was assigned inside the JSObject constructor and refers to the javascript * lookup table location for the javascript object. * @param id The ID of the javascript object. */ void release(int id){ String ID_KEY = JSObject.ID_KEY; String PROP_REFCOUNT = JSObject.PROP_REFCOUNT; String lt = jsLookupTable; String p = lt+"["+id+"]"; String js = "var id = "+id+"; "+ "if (typeof(id) != 'undefined' && typeof("+lt+"[id]) != 'undefined' && "+lt+"[id]."+ID_KEY+"==id){"+ p+"."+PROP_REFCOUNT+"--;"+ "if ("+p+"."+PROP_REFCOUNT+"<=0){"+ "delete "+lt+"[id];"+ "}"+ "}"; exec(js, true); } /** * Cleans up stale references to Javascript objects. This is triggered randomly whenever * a JSObject is constructed (with a given probability threshold). If this is never called * then the JS GC won't be able to free any objects that have ever been wrapped by JSObject * because they are stored in the global lookup table. */ public void cleanup(){ if ( DEBUG ){ Log.p("Cleaning up Javascript lookup table."); } ArrayList remove = new ArrayList(); for ( Integer i : objectMap.keySet()){ if ( Display.getInstance().extractHardRef(objectMap.get(i)) == null ){ remove.add(i); } } if ( DEBUG ){ Log.p("Found "+remove.size()+" objects to remove from the Javascript lookup table."); } for ( Integer i : remove ){ release(i.intValue()); objectMap.remove(i); } } private String exec(String js){ synchronized (browser) { return exec(js, false); } } /** * Executes a Javascript string and returns the string. It is synchronized * to disallow multiple threads from running javascript on the same BrowserComponent. * *

This is just a thin wrapper around the BrowserComponent.executeAndReturnString() method.

* * @param js * @return The string result of executing the Javascript string. */ private String exec(String js, boolean async){ synchronized (browser) { if ( DEBUG ){ Log.p("About to execute("+async+") "+js); //browser.execute("console.log(execute ca_weblite_codename1_js_JavascriptContext_LOOKUP_TABLE0[0])"); } if (async) { browser.execute(installCode()+";("+js+")"); return null; } else { return browser.executeAndReturnString(installCode()+";("+js+")"); } } } /** * Uninstalls the context from the browser component. This just includes * the listeners that are registered with the BrowserComponent so that * the context is informed of navigation callbacks and script message listeners. * * @see install() * */ private void uninstall(){ //browser.removeWebEventListener("shouldLoadURL", urlListener); browser.setBrowserNavigationCallback(previousNavigationCallback); browser.removeWebEventListener("scriptMessageReceived", scriptMessageListener); } /** * Installs the context in the current browser component. This effectively * installs listeners in the browser component so that the context can * be notified of events like navigation callbacks and script message received * events. */ private void install(){ //browser.addWebEventListener("shouldLoadURL", urlListener); previousNavigationCallback = browser.getBrowserNavigationCallback(); browser.setBrowserNavigationCallback(browserNavigationCallback); browser.addWebEventListener("scriptMessageReceived", scriptMessageListener); } /** * Executes a javascript string and returns the result of the execution as * an appropriate object value depending on the type of value that was returned. * *

Return value types will depend on the Javascript type returned. The following * table shows the mappings:

* * * * * * * * * * * * * *
Javascript TypeJava Return Type
Numberjava.lang.Double
Stringjava.lang.String
Booleanjava.lang.Boolean
ObjectJSObject
FunctionJSObject
nullnull
undefinednull
* *
Example
*
     * //Get the window object
     * JSObject window = (JSObject)ctx.get("window");
     * 
     * // Create a new empty Javascript Object
     * JSObject newObj = (JSObject)ctx.get("{}");
     * 
     * // Get the current document body contents as a string.
     * String html = (String)ctx.get("document.body.innerHTML");
     * 
     * // Get a numerical result
     * Double result = (Double)ctx.get("1+2");
     * 
     * // Get a Javascript function object
     * JSObject func = (JSObject)ctx.get("function(a,b){ return a+b }");
     * 
     * // Get a boolean result
     * Boolean res = (Boolean)ctx.get("1 < 2");
     * 
* @param javascript The javascript to be executed. * @return The result of the javascript expression. */ public Object get(String javascript){ synchronized(browser) { String returnVar = RETURN_VAR+"_"+(callId++); try { String js2 = returnVar+"=("+javascript+")"; String res = exec(js2); String typeQuery = "typeof("+returnVar+")"; String type = browser.executeAndReturnString(typeQuery); try { if ( "string".equals(type)){ return res; } else if ( "number".equals(type)){ return Double.valueOf(res); } else if ( "boolean".equals(type)){ return "true".equals(res)?Boolean.TRUE:Boolean.FALSE; } else if ( "object".equals(type) || "function".equals(type)){ return new JSObject(this, returnVar); } else { return null; } } catch ( Exception ex){ Log.e(new RuntimeException("Failed to get javascript "+js2+". The error was "+ex.getMessage()+". The result was "+res+". The type result was "+type)); return null; } } finally { browser.execute(returnVar+"=undefined"); } } } /** * Returns a reference to the Javascript "window" object. * @return The window object. */ public JSObject getWindow() { if (window == null) { window = (JSObject)this.get("window"); } return window; } /** * Returns the result of the provided javascript expression asynchronously. * @param javascript A javascript expression. * @param callback Callback to be called with the result of the expression. */ public void getAsync(String javascript, final Callback callback) { final String callbackMethod = "callback$$"+callbackId; callbackId++; if (callbackId > 1000) { callbackId = 0; } getWindow().set(callbackMethod, new JSFunction() { public void apply(JSObject self, Object[] args) { callback.onSucess(args[0]); getWindow().set(callbackMethod, null, true); } }, true); String js2 = callbackMethod+"("+javascript+")"; exec(js2, true); } /** * Returns the result of the provided javascript expression asynchronously. * @param javascript A javascript expression. * @param callback Callback to be called with the result of the expression. */ public void getAsync(String javascript, final SuccessCallback callback) { getAsync(javascript, new CallbackAdapter() { @Override public void onSucess(Object value) { callback.onSucess(value); } }); } /** * Sets a Javascript value given a compatible Java object value. This is an abstraction * upon javascript to execute key = value. * *

The key is any Javascript expression whose result can be assigned. The value * is a Java object that will be converted into a Javascript object as follows:

* * * * * * * * * * * * * * *
Java typeConverted to
DoubleNumber
IntegerNumber
FloatNumber
LongNumber
StringString
JSObjectObject by ref
nullnull
* *

Hence if you want to set a Javascript string value, you can just * pass a Java string into this method and it will be converted.

* *
JSObject "By Ref"
*

You may notice that if you pass a JSObject as the value parameter, the * table above indicates that it is passed by reference. A JSObject merely * stores a reference to a Javascript object from a lookup table in the * Javascript runtime environment. It is this lookup that is ultimately * assigned to the "key" when you pass a JSObject as the value. This has * the effect of setting the actual Javascript Object to this value, which * is effectively a pass-by-reference scenario.

* *
Examples
* *
     * // Set the window.location.href to a new URL
     * ctx.set("window.location.href", "http://google.com");
     * 
     * // Create a new JSObject, and set it as a property of another JSObject
     * JSObject camera = (JSObject)ctx.get("{}");
     * ctx.set("window.camera", camera);
     * 
     * // Set the name of the camera via JSObject.set()
     * camera.set("name", "My Camera");
     * 
     * // Get the camera's name via Javascript
     * String cameraName = (String)ctx.get("window.camera.name");
     *     // Should be "My Camera"
     * 
     * // Set the camera name via context.set()
     * ctx.set("camera.name", "New name");
     * 
     * String newName = (String)camera.get("name");
     *     // Should be "New name"
     * 
     * 
* @param key A Javascript expression whose result is being assigned the value. * @param value The object or value that is being assigned to the Javascript variable * on the left. */ public void set(String key, Object value){ synchronized(browser) { String lhs = key; String rhs = "undefined"; if ( String.class.isInstance(value)){ String escaped = StringUtil.replaceAll((String)value, "\\", "\\\\"); escaped = StringUtil.replaceAll(escaped, "'", "\\'"); rhs = "'"+escaped+"'"; } else if ( value instanceof Integer || value instanceof Long || value instanceof Float || value instanceof Double ){ rhs =value.toString(); } else if ( JSObject.class.isInstance(value)){ rhs = ((JSObject)value).toJSPointer(); } else if (value instanceof Boolean){ rhs = ((Boolean)value).booleanValue()?"true":"false"; } else { rhs = "null"; } exec(lhs+"="+rhs); } } /** * Sets a Javascript value given a compatible Java object value. This is an abstraction * upon javascript to execute key = value. See {@link #set(java.lang.String, java.lang.Object) for a full description. * @param key A Javascript expression whose result is being assigned the value. * @param value The object or value that is being assigned to the Javascript variable * on the left. * @param async If true, the call is made asynchronously. * @see #set(java.lang.String, java.lang.Object) * @see #setAsync(java.lang.String, java.lang.Object) */ public void set(String key, Object value, boolean async) { if (async) { setAsync(key, value); } else { set(key, value); } } /** * Sets a Javascript value given a compatible Java object value asynchronously. * @param key A Javascript expression whose result is being assigned the value. * @param value The object or value that is being assigned to the Javascript variable * on the left. * @see #set(java.lang.String, java.lang.Object) */ public void setAsync(String key, Object value) { String lhs = key; String rhs = "undefined"; if ( String.class.isInstance(value)){ String escaped = StringUtil.replaceAll((String)value, "\\", "\\\\"); escaped = StringUtil.replaceAll(escaped, "'", "\\'"); rhs = "'"+escaped+"'"; } else if ( value instanceof Integer || value instanceof Long || value instanceof Float || value instanceof Double ){ rhs =value.toString(); } else if ( JSObject.class.isInstance(value)){ rhs = ((JSObject)value).toJSPointer(); } else if (value instanceof Boolean){ rhs = ((Boolean)value).booleanValue()?"true":"false"; } else { rhs = "null"; } exec(lhs+"="+rhs, true); } /** * Calls the appropriate callback method given a URL that was received * from the NavigationCallback. It is set up to accept URLs of the * form cn1command:object.method?type1=value1&type2=value2&...&typen=valuen * *

This method parses the URL and converts all arguments (including the * object and method) into their associated Java representations, then * generates a JavascriptEvent to fire on the scriptMessageReceived * browser event.

* *

This method will usually be called on the native platform's GUI * thread, but it dispatches the resulting JavascriptEvent on the EDT * using Display.callSerially()

* @param request The URL representing the command that is being called. */ private void dispatchCallback(final String request){ Runnable r = new Runnable(){ public void run(){ String command = request.substring(request.indexOf("/!cn1command/")+"/!cn1command/".length()); // Get the callback id String objMethod = command.substring(0, command.indexOf("?")); command = command.substring(command.indexOf("?")+1); final String self = objMethod.substring(0, objMethod.indexOf(".")); String method = objMethod.substring(objMethod.indexOf(".")+1); // Now let's get the parameters String[] keyValuePairs = Util.split(command, "&"); //Vector params = new Vector(); int len = keyValuePairs.length; Object[] params = new Object[len]; for ( int i=0; iThis is intended to only process functions that are backed by * a JSFunction object. Prior to this call, it is assumed that a JSFunction * has been registered as a callback at the Javascript address provided via * the JSObject.addCallback() or JavascriptContext.addCallback() methods.

* *

If there is no JSFunction registered to handle this command then nothing * will happen as a result of the request.

* * @see JSFunction * @see addCallback() * @see JSObject.addCallback() * */ private class ScriptMessageListener implements ActionListener { public void actionPerformed(ActionEvent evt) { JavascriptEvent jevt = (JavascriptEvent)evt; JSObject source = jevt.getSelf(); String method = jevt.getMethod(); String key = source.toJSPointer()+"."+method; JSFunction func = (JSFunction)callbacks.get(key); if ( func == null ){ // No callback is registered for this method. return; } func.apply(source, jevt.getArgs()); evt.consume(); } } /** * Stock Javascript code that is included before all javascript requests to create * a lookup table for the JS objects if one hasn't been created yet. * @return */ private String installCode(){ return "if (typeof("+jsLookupTable+") == 'undefined'){"+jsLookupTable+"=[]}"; } /** * Adds a JSFunction to handle calls to the specified Javascript object. This * essentially installed a Javascript proxy method that sends a message via * a navigation callback to the JavascriptContext so that it can cause Java * code to be executed. * * * @param source The Javascript object on which the callback is being registered * as a member method. * @param method The name of the method that will be created to execute our callback. * @param callback The callback that is to be executed when source.method() is * executed in Javascript. */ void addCallback(JSObject source, String method, JSFunction callback, boolean async){ String key = source.toJSPointer()+"."+method; callbacks.put(key, callback); String id = JSObject.ID_KEY; //String lookup = LOOKUP_TABLE; String self = source.toJSPointer(); String isSimulator = Display.getInstance().isSimulator() ? "true":"false"; String js = self+"."+method+"=function(){"+ "var len=arguments.length;var url='https://www.codenameone.com/!cn1command/"+self+"."+method+"?'; "+ "for (var i=0; iThis operates almost exactly like the Javascript Function.apply() method.

* *

Note that JSObject also has a couple of call() methods * that may be more convenient to use as they will automatically set the "self" * parameter to the JSObject callee. This version of the method is handy in cases * where you have been passed a function (perhaps as a callback) and you need to * execute that function in a particular context.

* *
Example
* *
     * // Get the Array.push method as an object
     * JSObject push = (JSObject)ctx.get("Array.prototype.push");
     * 
     * // Create a new array
     * JSObject colors = (JSObject)ctx.get("['red', 'green', 'blue']");
     * 
     * // "Push" a new color onto the array directly using the JSObject's call()
     * // method
     * colors.call("push", "purple");
     * 
     * // Alternate method using JavascriptContext.call()
     * ctx.call(push, colors, "orange");
     * 
     * // Check size of colors array now
     * Double size = (Double)colors.get("length");
     *     // Should be 5.0
     * 
     * // Get 4th color (should be purple)
     * String purple = (String)colors.get(3);
     * 
     * // Get 5th color (should be orange)
     * String orange = (String)colors.get(4);
     * 
* * * * @param func The Javascript function object that is being called. * @param self Javascript Object that should act as "this" for the function call. * @param params The parameters that should be passed to the function. These * parameters should be passed as Java objects but will be converted into their * associated Javascript version. * @return The result of the function call. Javascript results will be automatically * converted to their associated Java types. */ public Object call(JSObject func, JSObject self, Object[] params){ return call(func.toJSPointer(), self, params); } /** * Calls a Javascript function (encapsulated in a JSObject) with a specified * Javascript Object as the "this" context for the function call. * @param func The Javascript function object that is being called. * @param self Javascript Object that should act as "this" for the function call. * @param params The parameters that should be passed to the function. These * parameters should be passed as Java objects but will be converted into their * associated Javascript version. * @param callback The callback to pass the return value to. */ public void callAsync(JSObject func, JSObject self, Object[] params, Callback callback) { callAsync(func.toJSPointer(), self, params, callback); } /** * Calls a Javascript function (encapsulated in a JSObject) with a specified * Javascript Object as the "this" context for the function call. * @param func The Javascript function object that is being called. * @param self Javascript Object that should act as "this" for the function call. * @param params The parameters that should be passed to the function. These * parameters should be passed as Java objects but will be converted into their * associated Javascript version. * @param callback The callback to pass the return value to. */ public void callAsync(JSObject func, JSObject self, Object[] params, final SuccessCallback callback) { callAsync(func, self, params, new CallbackAdapter() { @Override public void onSucess(Object value) { callback.onSucess(value); } }); } /** * Calls a Javascript function with the given parameters. This would translate * roughly into executing the following javascript: * * jsFunc.call(self, param1, param1, ..., paramn) * * * * @param jsFunc A javascript expression that resolves to a function object that * is to be called. * @param self The Javascript object that is used as "this" for the method call. * @param params Array of the Javascript parameters, as Java objects. These use * the same conversions as are described in the docs for set(). * * @return Returns the return value converted to the corresponding Java * object type. */ public Object call(String jsFunc, JSObject self, Object[] params) { return call(jsFunc, self, params, false, null); } /** * Calls a Javascript function with the given parameters asynchronously. This would translate * roughly into executing the following javascript: * * jsFunc.call(self, param1, param1, ..., paramn) * * * * @param jsFunc A javascript expression that resolves to a function object that * is to be called. * @param self The Javascript object that is used as "this" for the method call. * @param params Array of the Javascript parameters, as Java objects. These use * the same conversions as are described in the docs for set(). * * @param callback Callback to pass the return value converted to the corresponding Java * object type. */ public void callAsync(String jsFunc, JSObject self, Object[] params, Callback callback) { call(jsFunc, self, params, true, callback); } /** * Calls a Javascript function with the given parameters asynchronously. This would translate * roughly into executing the following javascript: * * jsFunc.call(self, param1, param1, ..., paramn) * * * * @param jsFunc A javascript expression that resolves to a function object that * is to be called. * @param self The Javascript object that is used as "this" for the method call. * @param params Array of the Javascript parameters, as Java objects. These use * the same conversions as are described in the docs for set(). * * @param callback Callback to pass the return value converted to the corresponding Java * object type. */ public void callAsync(String jsFunc, JSObject self, Object[] params, final SuccessCallback callback) { callAsync(jsFunc, self, params, new CallbackAdapter() { @Override public void onSucess(Object value) { callback.onSucess(value); } }); } long callId = 0; /** * Calls a Javascript function with the given parameters, and optionally to make the call asynchronously. This would translate * roughly into executing the following javascript: * * jsFunc.call(self, param1, param1, ..., paramn) * @param jsFunc A javascript expression that resolves to a function object that * is to be called. * @param self The Javascript object that is used as "this" for the method call. * @param params Array of the Javascript parameters, as Java objects. These use * the same conversions as are described in the docs for set(). * @param async If true, the call will be made asynchronously. * @param callback Used if {@code async} is true to pass the return value. * @return Returns the return value converted to the corresponding Java * object type. This will always return null if {@code async} is {@code true}. */ public Object call(String jsFunc, JSObject self, Object[] params, boolean async, Callback callback){ if (callId > 10000000l) { callId = 0; } String var = RETURN_VAR+"_call_"+(callId++); String js = var+"=("+jsFunc+").call("+self.toJSPointer(); int len = params.length; for ( int i=0; ijsFunc.call(self, param1, param1, ..., paramn)
* @param jsFunc A javascript expression that resolves to a function object that * is to be called. * @param self The Javascript object that is used as "this" for the method call. * @param params Array of the Javascript parameters, as Java objects. These use * the same conversions as are described in the docs for set(). * @param async If true, the call will be made asynchronously. * @param callback Used if {@code async} is true to pass the return value. * @return Returns the return value converted to the corresponding Java * object type. This will always return null if {@code async} is {@code true}. */ public Object call(String jsFunc, JSObject self, Object[] params, boolean async, final SuccessCallback callback){ return call(jsFunc, self, params, async, new CallbackAdapter() { @Override public void onSucess(Object value) { callback.onSucess(value); } }); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy