Scripting the techexplorer Hypermedia Browser

Alternative Communication Layer via JavaScript


Applets may also be constructed to use techexplorer indirectly. Rather than being passed a reference to a techexplorerPlugin or techexplorerControl object, the applet may rely on JavaScript to handle communication with the external techexplorer component. In this design, the applet only needs to provide accessor methods to relevant data. For example, a get and set method pair would be sufficient to modify or retrieve a TeX-formatted string from the applet, which JavaScript would send to techexplorer.

It is not uncommon to write the Java source code simultaneously with JavaScript and HTML code. To help distinguish the different languages, blue will represent Java code, red will represent JavaScript code, and green will represent HTML code in this description page.

Note: This design can be used in all current versions of Internet Explorer and in Netscape 4. While later versions of Netscape support many features of Netscape 4 plugins, support for the LiveConnect technology used to implement techexplorer scripting is no longer available. See the Compatibility section for details.

Note: JavaScript calls to techexplorer in later versions of Netscape fail silently, returning empty strings without reporting errors or exceptions to the browser console windows. Plugin scripting support for these versions of Netscape is planned for a future release of techexplorer.

Creating the Applet

In creating an applet to interact with techexplorer via JavaScript, the application can be arranged so the applet is not technically aware that techexplorer exists. It provides public methods to access certain data, but does not know what code or objects are calling those methods. Minimally, the applet needs to provide a get method so JavaScript can pull data from the applet and hand it to techexplorer. A set method should also be added to allow external control of the applet. Additionally, we'd like the applet to display this raw data. In this example, a java.awt.TextArea member named textarea takes care of the display. The code for the creation and insertion of the TextArea can be found in the Java source file, along with additional comments that have been removed from the methods displayed in this page. The accessor methods used are copied below.

    public String getCurrentString()
      {
      return this.textarea.getText();
      } // ends getCurrentString(void)

    public void setCurrentString(final String tex)
      {
      this.textarea.setText(tex);
      } // ends setCurrentString(String)

Creating the HTML

In order to accommodate both the Netscape plugin model and the Microsoft ActiveX model, we use the traditional object/embed pair to place our target techexplorer component into the page.

    <object classid="clsid:5AFAB315-AD87-11D3-98BB-002035EFB1A4"
               name="te_control" width="400" height="200">
      <param name="DataType" value="0" />
      <param name="Data" value="\LaTeX sample" />
      <embed type="application/x-techexplorer"
             name="te_plugin" width="400" height="200"
      pluginspage="http://www.integretechpub.com/techexplorer/"
       texdata="\LaTeX sample">
        <noembed>
          <p>
Integre techexplorer Hypermedia Browser not installed!
Please visit the <a href="http://www.integretechpub.com/techexplorer/"
                  target="_blank">techexplorer home page</a>
for more information.
          </p>
        </noembed>
      </embed>
    </object>

We wrap the object tag around the embed tag so Internet Explorer sees the object and therefore ignores the internal embed tag. Similarly, Netscape doesn't understand the object tag and so it continues inward to find the embed tag. If the browser understands neither of these tags, or does not have techexplorer installed, the noembed contents will be displayed.

It's generally a good idea to have the attributes match up in both the object and the embed tags. The width, height, and texdata attributes will all affect the initial appearance of the techexplorer component, and you probably want them the same in whatever browser is being used. The exception here is the name attribute, which must be different in the two models. The object tag refers to the techexplorer ActiveX Control as "te_control", while the embed tag refers to the techexplorer Plugin as "te_plugin".

Of course, we'll also need an applet tag in the page somewhere. In our example, the Java applet class name is AltCommLayer.

    <applet code="AltCommLayer" width="400" height="150" mayscript="true">
      <param name="texdata" value="\LaTeX sample" />
      <p>
        Java is either not installed or not enabled.
        Please visit <a href="http://java.sun.com/"
                      target="_blank">Java's homepage</a>
        for install information.
      </p>
    </applet>

As usual, we provide some text inside the applet tag in case the user either doesn't have Java, or has disabled it. If Java is enabled, the text will not be displayed.

Creating the JavaScript

The first task of the JavaScript is to determine which of the two techexplorer components is being used in the HTML page. To this end, we use a single global variable (which we initialize to null) to house the reference to the component.

    te=null;

Unfortunately, the system may not be completely ready when the JavaScript first executes. To allow for load-time synchronization, we'll shift the inspection code to a JavaScript function, which we may call whenever we're unsure of the component type or presence.

    function assign_te()
      {
      if (document.te_plugin)
        te = document.te_plugin;
      else if (document.te_control)
        te = document.te_control;
      else
        {
        alert("Integre techexplorer not found.  Please visit\n" +
              "http://www.integretechpub.com/techexplorer/\n" +
              "for the latest version.");
        } // ends else

      } // ends function assign_te(void)

Now we attempt to call this function using the onload event of the HTML body tag.

    <body onload="assign_te();">

Additionally, and in case of initial failure due to load-time synchronization, we can test the validity of the te variable and potentially attempt to re-execute assign_te() whenever we need to access techexplorer. Here is the method used to pass a new string into the techexplorer component:

    function setTeXString(latex)
      {
      if (te == null)
        {
        assign_te();
        if (te == null)
          return;
        } // ends if

      te.reloadFromTeXString(latex);
      } // ends function setTeXString(String)

reloadFromTeXString is the method that replaces the techexplorer content. Since we want to be able to round-trip the data, we will use the printTeXInput method to extract the current data from techexplorer.

    function getTeXString()
      {
      if (te == null)
        {
        assign_te();
        if (te == null)
          return "techexplorer not found";
        } // ends if

      return te.printTeXInput();
      } // ends function getTeXString(void)

Triggering Updates

Finally, there is the question of how to initiate an update using new data entered by the user. Since data can flow in to and out from the applet, the new data may be either in the applet's text area, or the techexplorer content may have been changed using the "Control properties..." option from the techexplorer right-click context menu. In our example we are interested in two different events: one to send data from the applet to techexplorer, and one to send data from techexplorer to the applet.

There are at least two ways to trigger the update events. The simplest is to insert HTML buttons in the page which, when pressed, call the functions outlined above and interact with the applet. We would have to provide the applet a name in the applet tag to use this design. Assuming the name was foo, the HTML for the buttons may look something like this:

    <input type="button" value="Update techexplorer"
        onclick="setTeXString(foo.getCurrentString());" />
    <input type="button" value="Update applet"
        onclick="foo.setCurrentString(getTeXString());" />

In our example, we elected to use a slightly more complicated approach: the buttons to initiate the update events reside within the applet itself. One benefit of this approach is that you can make the buttons blend into your applet design, or have the event triggered automatically from a Java TextEvent. In this design, the applet needs to be able to communicate with the containing HTML page, which can be done using the netscape.javascript.JSObject Java class. (Note that this technique will work in both Netscape and Internet Explorer.) We begin by asking the JSObject class for a reference to the surrounding page.

    JSObject html = JSObject.getWindow(this);

We should store this reference in a member variable so we can make calls out to JavaScript whenever we'd like. Using the ActionListener interface, we could expect to see a method similar to the following example to handle our button events:

    public void actionPerformed(final ActionEvent ae)
      {
      final String command = ae.getActionCommand();
      if (command == null || command.equals(""))
        return;
      else if (command.equals("broadcast"))
        {
        this.html.call("setTeXString",
                       new Object[] { this.getCurrentString() });
        } // ends else if

      else if (command.equals("receive"))
        {
        this.setCurrentString((String) this.html.call("getTeXString",
                                                      null));
        } // ends else if

      } // ends actionPerformed(ActionEvent)

The complete Java source for the AltCommLayer class can be found here, and contains additional comments for your assistance. The compiled example can be executed using the button below.

Click to try the Javascript Layer.


Click here to to view the previous section. Click here to to view the next section.

Integre techexplorer Hypermedia Browser is a trademark of Integre Technical Publishing.
Send comments and questions to techexplorer@integretechpub.com.
Visit the official techexplorer home page at http://www.integretechpub.com/techexplorer/.