Home
Categories
Dictionary
Download
Project Details
Changes Log
FAQ
License

Javascript properties and functions



Javascript scripts are available through the JSScriptWrapper wrapper. This article explains how to add properties and built-in functions for Javascript scripts.

Overview

In addition to the abilities that Javascript scripts share with other scripting languages, it is also possible to add built-in fonctions, such as for example:
      helloWorld: function() {
        alert("Hello World!");
      }      
and also properties, such as for example:
      getLabel: function(identifier) {
        return document.getElementById(identifier).label;
      }      
Adding these elements is supported by the JSScriptable interface.

The simplest way is to subclass its abstract implementation AbstractJSScriptable and set it to the wrapper by JSScriptWrapper.setScriptable(JSScriptable).

Adding built-in functions

To add built-in functions, you must implement the JSScriptable.getFunctionProperties() method to return the list of built-in function names. Each of the names defined in this array must correspond to one public method in your subclass.

Example

For example if you want to support the print(message), you must define the two following methods:
      public class MyScriptable extends AbstractJSScriptable {
        public void print(String message) {
          context.echo(message);
        }

        public String[] getFunctionProperties() {
          String[] array = { "print" };
          return array;
        }  
      }
This will allow this kind of script:
      helloWorld: function() {
        print("Hello World!");
      }      

Managing properties

To add properties, you must:
  • Implement the JSScriptable.getObjectNames() method to return the list of properties provided by the script
  • Provide one or several ScriptableExecutor classes for the properties:
    • Use the JSScriptable.getExecutorClass() method if you have only one executor. This should be the case if you only have one property. The executor will be called for all methods, getters, and setters on the property
    • Use the JSScriptable.getExecutorsMap() method if you have more than one executor. This should be the case if you only have more than one property. The keys of the Map are the properties names, and each executor will be called for all methods, getters, and setters on its associated property

The ScriptableExecutor

The ScriptableExecutor must be a ScriptableObject and must implement the ScriptableExecutor interface, with only one method: Yuou must implement several methods in the executor for methods or sub-properties applied on the property or properties associated with the executor:
  • As the executor is a ScriptableObject, you must implement the getClassName() method and return the simple name of the executor class. Alternatively, you can subclass the AbstractScriptableExecutor class which implements this method for you
  • For a getter on a property, you must implement a public Object jsGet_<property name>() method in the executor
  • For a setter on a property, you must implement a public void jsSet_<property name>(Object value) method in the executor
  • For a method on a property, you must implement a public void jsFunction_<method name>(Object... params) method in the executor
For example in a script:
      myExample: function() {
        value = document.label; // example of a property getter
        document.label = value; // example of a property setter
        value = document.getName(); // example of a method applied on a property     
      }      

Having more than one ScriptableExecutor

If you support more than one property, there is a good chance that you will have the same sub-properties or method names on different properties. In that case, you should implement the JSScriptable.getExecutorsMap() method rather than the JSScriptable.getExecutorClass() method.

Example with only one property

For example if you want to support the document property, you must define the two following methods:
      public class MyScriptable extends AbstractJSScriptable {

        public String[] getObjectNames() {
          String[] array = { "document" };
          return array;
        }  
      
        public Class<? extends ScriptableObject> getExecutorClass() {
          return MyExecutor.class
        }        
      }
We could also add a getDocumentName() method to return the document name:
      public class MyScriptable extends AbstractJSScriptable {

        public String[] getObjectNames() {
          String[] array = { "document" };
          return array;
        }  
      
        public Class<? extends ScriptableObject> getExecutorClass() {
          return MyExecutor.class
        }       
      
      
           public String getDocumentName() {
             return "TheName";
           }
      
      }
With the following executor class:
      public class MyExecutor extends AbstractScriptableExecutor {
        private MyScriptable scriptable;

        public TheExecutor() {
        }

        public void setup(JSScriptable scriptable) {
          this.scriptable = (MyScriptable) scriptable;
        }

        public Object jsFunction_getName() {
          return scriptable.getDocumentName();
        }  
      }
This will allow this kind of script:
      myFunction: function() {
        return document.getName();
      }      

Adding external functions


It is possible to implement Javascript functions by methods provided by other scripts. This can be useful if you want to easily interoperate with other scripts.

For example in the following script the doSomething(int) method can be provided by another script (which can even not be a Javascript script):
      myScrip: function() {
        value = doSomething(10);
        return value;
      }      

See also


Categories: impls

Copyright 2019-2020 Herve Girod. All Rights Reserved. Documentation and source under the BSD licence