Duncan Temple Lang

1/ 3/ 20015/ 4/ 2001

Table of Contents

  1. Initializing a plugin.
    1. Accessing S from JavaScript
      1. The RNetscape Methods
      2. Multiple Plugin Instances
        1. Accessing JavaScript from R
          1. The Graphics Plugin
            1. Bibliography
            2. 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.

            1. Initializing a plugin.

            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.
          2. debug
          3. If present, internal debugging information from the plugin is written to the file /tmp/NetscapePlugin.log.
          4. init
          5. 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.

            2. Accessing S from JavaScript

            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.
          6. eval
          7. 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.
          8. call
          9. 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.
          10. namedArgCall
          11. 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);
            
          12. Standard functions
          13. 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.

            3. Multiple Plugin Instances

            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.

            4. Accessing JavaScript from R

            Just as we can access S from JavaScript, we can access JavaScript objects from S. This includes 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 [1] .

            5. The Graphics Plugin

            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.

            Bibliography

            1. JavaScript: The Definitive Guide, David Flanagan,
            2. JavaScript Guide, http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html Valid on: 02/ 2001

            Footnotes

            1. This may not be a good idea as the objects to which these references point may disappear asynchronously.