Difference between revisions of "RAP/Incubator/ClientScripting"

From Eclipsepedia

< RAP
Jump to: navigation, search
(JavaScript Hints for Java Developer)
(Noteable similarities between Java and JavaScript)
Line 185: Line 185:
  
 
* <b>System.out.println and console.log</b>
 
* <b>System.out.println and console.log</b>
Most browser (but not all!) have some form of javascript console. They all have at least one function in common that can be used like <code>System.out.println</code>, which is <code>console.log</code>. Some browser also have <code>console.trace</code>. Browser not supporting <code>console.log</code> (or in case of InternetExplorer, not having it activated), will crash when calling that method, so remember removing them after debugging.
+
Most browser (but not all!) have some form of javascript console. They all have at least one function in common that can be used like <code>System.out.println</code>, which is <code>console.log</code>. Some browser also have <code>console.trace</code>. Browser not supporting <code>console.log</code> (or in case of InternetExplorer, not having it activated), will crash when calling that method, so remember removing all occurrences of console from your JavaScript code after debugging.
  
 
* <b>Math and Math</b>
 
* <b>Math and Math</b>

Revision as of 12:21, 6 February 2012

Contents

Overview

Conventional RAP applications are running almost entirely on a Server, with a thin client only rendering a user interface with some limited interactivity. This has several advantages, but it also means all application-relevant events have to be forwarded to the Server before being processed, causing small delays and traffic. Scenarios where interactions occur with a high frequency, like typing or mouse movements, would therefore be undesirable.

This is where RAP ClientScripting can help. ClientScripting allows developers to handle some of the events directly on the client, without creating any http-requests. This is ideal to customize or enhance the behavior of specific widgets, making it much less often necessary to develop RAP custom-widgets.

The scripts themselves are written in JavaScript on a SWT-like API. This allows application developers with SWT-experience to get started right away, and makes porting between SWT/Java and RAP-ClientScripting fairly easy. Even without any JavaScript-experience, this document should provide you with all the basics.

The ClientScripting feature is currently in early development, aiming to enable only some specific use cases at first. However, all API published here should be stable and is unlikely (but currently not guaranteed) to change in the future. The project is currently hosted on GitHub.

Questions, suggestions and bug reports are welcome!

Java API

Client event processing works like untyped event handling in SWT, with the main difference that the handler itself has to be written in JavaScript, and is added to the widget using the listener itself instead of the widget. It also does (naturally) not have access to all of the resources and functionality that would be available on the server.

The ClientListener Class

Instances of this class represent a JavaScript function that can be attached to any widget for any supported event. It's similar in concept to org.eclipse.swt.widgets.Listener, but can only be executed on the client.

Constructor Summary
ClientListener( String scriptCode )
Creates an instance of ClientListener using the given String as JavaScript source code.

The JavaScript source code has to start with "function( event ){" and end with the closing "}" of the function body. For the documentation of the "event" object, see the JavaScript chapter below. Note that the function is executed without any context ("this"), meaning that unlike the SWT handleEvent method, it is not a member of an object.

Method Summary
void bindTo(Widget widget, int eventType)
Adds the listener to the given widget and event type. The supported event types are constants of this class.
void dispose()
boolean isDisposed()

JavaScript API

The Event Object

This object is given as the first argument when calling a client event listener function. Its API is designed after org.eclipse.swt.widgets.Event.

Field Summary
number type
the type of event, as defined by the event type constants in object SWT
Widget widget
an object representing the widget that issued the event.
boolean doit
depending on the event, a flag indicating whether the operation should be allowed. Setting this field to false will cancel the operation. Currently supported only for key and mouse events on Text and Text-like widgets.
string doit
depending on the event, the character represented by the key that was typed. This is the final character that results after all modifiers have been applied. For non-printable keys (like arrow-keys) this field is not set. Changing its value has no effect.
number keycode
depending on the event, the key code of the key that was typed, as defined by the key code constants in object SWT. When the character field of the event is ambiguous, this field contains the unaffected value of the original character. For example, typing Shift+M or M results in different characters ( 'M' and 'm' ), but the same keyCode (109, character code for 'm').
string character
depending on the event, the character represented by the key that was typed. This is the final character that results after all modifiers have been applied. For non-printable keys (like arrow-keys) this field is not set. Changing its value has no effect.
number stateMask
depending on the event, the state of the keyboard modifier keys and mouse masks at the time the event was generated.
number button
the button that was pressed or released; 1 for the first button, 2 for the second button, and 3 for the third button, etc.
number x
x coordinate of the pointer at the time of the event
number y
y coordinate of the pointer at the time of the event

The SWT Object

The SWT object contains a number of public contants. It is available as a local variable within the scope of any ClientScripting function. Its API is designed after org.eclipse.swt.SWT, but the values for the constants may be different. To get an overview of all available constants and their purpose, view the file "js/org/eclipse/rap/clientscripting/SWT.js" from the ClientScripting bundle.

The Widget Object

The Widget object in RAP ClientScripting is an abstract representation of an SWT widget. It has a subset of the API of the actual SWT Widget it represents. In some cases the API may slightly differ.

Setter

All widgets have setter functions for all properties defined in the RAP-Protocol. All setter take exactly one argument. For now a list of all the properties is available in the READNME.md in the ClientScripting bundle. Please be aware that as of now, changing a widgets property with these setter will in most cases only affect it's client side representation. Only properties that can also be changed by a user's interaction with the UI (like selection) will also be updated on the java widget instance. This will be improved in later versions to fully synchronize all properties.

Getter

Currently only some getters are available. A list of all properties that have getters is available in the README.md in the ClientScripting bundle. Note that the getter might return null, but never undefined.

setData and getData

The Widget provides object a setData and a getData function. Similar to SWT, these allow to attach data to a widget instance without affecting the widget itself. Unlike SWT any value can be stored with setData, not just objects. Note that the data storage on the client is not synchronized with the data storage on the actual SWT Widget.

Function Summary
undefined setData( string key, value value )
stores the given value. The key is mandatory.
value getData( string key )
gets a stored value. The key is mandatory.

Data Types

The type and format of the values that can be set/get on the widget objects is a javascript-specific approximation of its SWT counterpart. They are identical to those used in the RAP Protocol.

For simple data types/values the mapping is as follows:

SWT ClientScripting
void undefined
null null
boolean boolean
int number, but treated like int
float number
String string
char string with length of 1

For complex types see http://wiki.eclipse.org/RAP/Protocol#Common_Data_Types.

Restrictions and Discouraged Usage

For the RAP default client, ClientScripting runs in the same environment as the client itself. For reasons of stability, compatibility and security you should not:

  • Try to access any RAP client API not described here.
  • Manipulate any of the ClientScripting objects in an undocumented manner.
  • Access any DOM (HTML) elements.
  • Manipulate any of JavaScript's own prototypes/constructors (Object, Function, etc.).
  • Set a widget's property to any invalid/unsupported values.

Violating any of the above guidelines might create unpredictable results, even if the application seems to run fine at first.

Accessing the window/document Objects is discouraged for cross-browser/cross-client compaibility concerns. You can do so at your own risk.

Creating global variables is also heavily discouraged, and can easily happen by accident if a variable is created without the "var" keyword.

For security reasons you should be aware that, unlike RAP sourcecode written in Java, all ClientScripting functions (JavaScript sourcecode) are currently transferred to the client completely unaltered (including comments), and can be read by any user with enough technical expertice.

JavaScript Hints for Java Developer

Developers experienced with Java programming and less familiar with (or completely new to) JavaScript might find the following hints useful in regard to ClientScripting:

Noteable differences between Java and JavaScript

  • JavaScript variables are dynamically typed and have function scope

All local variables in JavaScript are delcared with "var" and can contain any type (undefined, null, number, boolean, string, object). It is not relevant at all where in the function it is declared, its scope is always the entire function.

  • Strings are not objects

Strings are primitives in JavaScript, and are compared with "==" (or "==="), not ".equals". However, string primitives can be coerced into a string object, on which several useful methods are available.

  • A number is not always a number

When calculating a numeric value in JavaScript, the result might not always be a number, even if it is of the type number. The two cases are infinity (e.g. "10/0 == infinity") and NaN (not a number, e.g. "Math.sqrt( -1 )"). NaN can be detected only by using isNaN (e.g. "isNaN( Math.sqrt( -1 ) ) == true"). If a number is neither NaN nor infinity, it can do most things Javas int or double can, including bitwise operations.

  • Arrays have dynamic length

Even though their syntax is very similar, JavaScript Arrays behave more like Java Lists than Java Arrays. They can store different types in different slots, and can change their length as needed. They also have differently named, but similarly working methods.

Noteable similarities between Java and JavaScript

  • Objects and Maps

JavaScript Objects (created with a literal "{}") can be used like Java Maps. A "map.put( "key", value )" would be "map[ key ] = value", and a " map.get( "key" )" would be "map[ "key" ] ". In JavaScript, value could be of any type.

  • System.out.println and console.log

Most browser (but not all!) have some form of javascript console. They all have at least one function in common that can be used like System.out.println, which is console.log. Some browser also have console.trace. Browser not supporting console.log (or in case of InternetExplorer, not having it activated), will crash when calling that method, so remember removing all occurrences of console from your JavaScript code after debugging.

  • Math and Math

The Java Math class and the JavaScript Math object have almost identical API.

  • Date and Date

The JavaScript constructor Date creates objects almost identical in API to instances of Javas Date class.

  • Regular Expressions and RegExp

JavaScript also supports regular expressions.

  • char and string

JavaScript has no char type. For ClientScripting, a string with a length of one character is used instead. This allows for comparison like "event.character == "A"", but not "event.character >= 65". To do that use charCodeAt. Example: "event.character.charCodeAt( 0 ) >= 65".