Duncan Temple Lang
1/
3/
20015/
4/
2001
-
Initializing a plugin.
-
Accessing S from JavaScript
-
The RNetscape Methods
-
Multiple Plugin Instances
-
Accessing JavaScript from R
-
The Graphics Plugin
-
Bibliography
-
Footnotes
Abstract
This is intended to be the reference manual for the S Plugin for
Netscape. It will describe the different features and options
for starting, controlling and terminating a plugin instance.
One creates an instance of the plugin using EMBED
tag in HTML. The TYPE attribute
should be the string app/x-sinterpreter
. In the
future, we will introduce 2 other MIME types. These will support R
graphics devices and also scripts. Since there is no
display associated with this plugin, one typically uses the
HIDDEN to avoid it taking any space
in the page.
One provides a name by which the S engine can be referenced
from JavaScript code using the NAME
of the EMBED element.
Any other attributes are passed to the C code that initializes
the plugin and processed there.
We currently recognize some attributes as having special meaning.
-
-
debug
-
If present, internal debugging information from the plugin
is written to the file /tmp/NetscapePlugin.log.
-
-
init
-
The value of this attribute is treated as an S expression
and is parsed and evaluated. This allows one to initialize the
S session when it is "created".
It is important to keep in mind that when the plugin is
loaded and initialized by the first page, the R session never
terminates. Instead, it remains in its current state when one leaves a page
and is used as-is when a new page that uses the plugin is loaded.
This means that one should program carefully and avoid global
variables, etc.
You can access S objects and call S functions from
within JavaScript code by treating the
S engine as a JavaScript (or more accurately, Java) object.
This means that you can invoke any of the predefined
methods defined by the RNetscape
Java class. (See below.)
The JavaScript code must first reference the plugin object.
This corresponds to the JavaScript variable whose name is
the same as that specified for the NAME
tag in the EMBED element.
As usual, one must be careful to use the correct scoping rules to
refer to the object. Usually, this is something
like
document.R
1. The RNetscape Methods
As mentioned above, JavaScript code can call any of the (public) methods
in an RNetscape instance, given a reference
to it. These methods are documented using Javadoc and maintained in
a separate file.
However, we give a basic overview of them here.
-
-
eval
-
One can execute S commands or expressions
that are given as strings using the
eval() and
and is parsed and evaluatedevalPrint()
methods. The former returns the object resulting from the evaluation
and the latter returns a string containing any printed output
generated when evaluating the expressions.
-
-
call
-
Evaluating strings (via the eval() methods)
is quite limited and often difficult.
Instead, we can call S functions directly and pass them
JavaScript objects. The collection of
call() methods provide a way to do this.
Named arguments are handled by namedArgCall.
-
-
namedArgCall
-
One can use namedArgCall()
to invoke S functions with named arguments.
Unfortanately, the constrcut is a little clumsy.
One specifies the arguments and the names in two
separate but parallel arrays.
For example, the following code calls the function
abline and specifies
the argument v with a value of 50.
args = new Array(50);
argNames = new Array("v");
R.namedArgCall("abline", argNames, args);
-
-
Standard functions
-
There is a small and growing collection of commonly
used S functions that are exported as Java methods
in the RNetscape class.
These include things such as
library(),
exists(),
get(),
remove(),
source()
It is relatively simple to add more methods to the
RNetscape. Please feel free
to suggest ones that you feel are commonly used.
In the future, we may provide a mechanism by which one can
specify the Java class associated with the Plugin instance
when the instance is created. This would then allow others
to use classes that extended RNetscape.
It is possible to have multiple Netscape windows
open simultaneously with two or more using an instance of the plugin.
Each plugin instance will have a unique instance of the
RNetscape Java class associated with it.
However, each instance
of the RNetscape class
will evaluate its calls to a single and shared
R engine. This means that if two plugin instances execute code
that stores intermediate values in a global variable within the S
session (i.e. in the global environment), then they can potentially
overwrite the value of the other instances version of that variable.
In other words, we have a race condition and this requires some form
of synchronization.
One approach to solving this is to use closures, or specifically
mutable objects in R.
These are a collection of functions that can see their own instance
of data, much like static variables in C.
Another approach is to use the new OOP
which basically builds on closures, etc. and presents a more traditional
object oriented system with fields local to an instance.
In the future, we will support multiple interpreters within R
and so different plugin instances will have their own namespace.
Just as we can access S from JavaScript, we can
access JavaScript objects from S.
This includes
- evaluating JavaScript commands (as strings)
- call JavaScript functions,
- access JavaScript variables and fields within JavaScript objects
These facilities allow us to access things
in a window such as documents, frames, links,
the URL being visited, etc.
The functions
.JavaScriptEval,
.JavaScriptCall,
.JavaScriptGetMember,
.JavaScriptSetMember,
.JavaScriptGetSlot,
.JavaScriptSetSlot
provide the low-level mechanisms to access the JavaScript
interpreter.
However, we have simplified these by providing higher-level S-language
constructs.
A JavaScript object appears in S as an object of class
JavaScriptReference.
Then one can access the fields or members
of the underlying JavaScript object
using the familiar [[
w <- getJavaScriptWindow()
w[["document"]]
w[["frames"]][1][["document"]][["form"]]
Similarly, one can access entries in a JavaScript array
using the [.
This currently uses 1 based counting as in the S-style rather than the
0-based indexing used by JavaScript.
Calling a JavaScript function or method is done
using the $ on the object
in which the function object is defined.
For example, suppose, within S, we have a reference to
a document object
and we want to replace its contents with some text we
generate in S.
Then we would call the document
object's open
and write methods.
doc$open()
doc$write(paste(names(myData)))
S programmers may be inclined to think of
writing a function that accesses a JavaScript
window and works from there. They may think there
should be a function getWindow
which would return a reference to the top-level
window associated with the plugin instance.
But there are problems with this approach.
Firstly, which plugin instance should be returned. Since there may be
multiple instaces of the plugin running within a single R, we need to
specify which one. Secondly, R is typically called in reponse to an
event or user action in the browser and the call to R is done by a
JavaScript event handler (e.g. the
onclick, etc.). This JavaScript code
can pass the window or any other JavaScript objects that the R code
will need. This is a good idea as it avoids global variables and makes
code more readable, adaptable and maintainable. if R needs to
asynchronously access JavaScript code, then it should
store a reference to the ojects it needs, essentially using global
or static variables in R.
We have added preliminary support for using the R X11 graphics device
within an HTML page to display R plots and general graphics. As with
the interpreter plugin, one creates an instance of the R X11 plugin
using the EMBED tag. The
TYPE attribute should be specified as
app/x-sgraphics
. Obviously, the graphics plugin is
intended to be seen, so one should not use the
HIDDEN.
Additionally, one should specify values for the
WIDTH and
HEIGHT attributes within the
EMBED tag.
The background attribute allows one
to specify a color for the background of the drawing area of the
graphics device. Netscape, rather than R, uses this to set the color.
The init attribute is used, as within
the interpreter plugin, to specify S commands that are run when the
plugin is initialized. This can be used to specialize the interpreter
and the associated session. For example, we might attach certain
libraries, assign session-specific global variables, etc.
The graphics plugin behaves much like the regular
interpreter plugin. In fact, the Java class that
connects JavaScript to the internal plugin is a simple
extension of the interpreter class. Therefore, from within
JavaScript code, one can invoke any of the different
methods provided by the interpreter plugin.
Methods such as call(),
get(),
eval(), etc. are available.
In addition to these inherited methods, the graphics plugin provides
utility methods for generating some of the standard plot types
such as histograms and scatter-plots.
Look at the
JavaDoc page for this plugin.
Currently, there are some issues to be resolved with the graphics
device relating to synchronization and events. Additionally, one will
need a recent version of R, specifically the development version
1.3.0. This contains minor generalizations for the X11 device that
were added around the 26th of March.
-
JavaScript: The Definitive Guide,
David Flanagan,
-
JavaScript Guide,
http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html
Valid on: 02/
2001
-
This may not be a
good idea as the objects to which these references point may disappear
asynchronously.