A Guide to Writing Tcl Applets

Applets are small programs which are executed within the context of another 'parent' application. SurfIt! is a 'parent' application which supports the execution of Tcl applets. Tcl applets use most of the features of the Tcl language and Tk toolkit, however there are some restrictions and special features of the environment in which the applet executes. This document describes those features.

Including Applets in HTML Documents

There are several methods for including a Tcl applet in a HTML document. An applet may be "inlined" at any point in the document by using an anchor element with the REL=embed attribute:

<A REL=embed HREF="applet">...</a>

Note that the use of the <A> tag may not be satisfactory in general, since <A> tags cannot be nested. The proposed <EMBED> tag may be used in the future. An applet may be specified as the destination anchor of a hyperlink, for example: <A HREF="tcl/appinfo.tcl">. In this case, the hyperpage is not cleared when the applet is loaded so that the applet may operate on the hyperdocument which invoked it.

Another method is to specify an applet as the SCRIPT attribute of a form, for example:

<FORM METHOD=GET ACTION="..." SCRIPT="applet">

Safety, Security and Privacy

Given that an applet may contain arbitrary code that is downloaded from a remote, autonomous source the issues of safety, security and privacy arise. Such applets are said to contain foreign code. SurfIt! addresses these issues as follows to ensure that the user's computer is not compromised in any way.

Safety
Foreign code may well suffer from programming errors (nobody's perfect!). Errors resulting from the execution of an applet should not affect the functioning of the browser.

Whenever SurfIt! executes foreign code any error conditions are caught and ignored.

Security
Foreign code is executed within a separate, restricted interpreter where it is forbidden from accessing operating/windowing system resources in any way which may compromise system security. To help avoid the possibility of Trojan Horses, windows created by the applet are marked so that user can determine whether to trust the window or not. See "Applet Execution" for more details.

The execution of one applet should not affect any other applets. For example, a malicious applet may wish to interfere with the operation of a competing vendor's applet. The applet execution environment guarantees that applet are kept completely independent of each other. However, there is a need for inter-applet communication in a safe, controlled manner.

Privacy
Applets are given access to network resources. For this reason an applet should not be allowed to gather any information about the user without the user's permission, since the applet could then transmit that information to a remote system. This includes any information contained within, or pertaining to, the user's computer system as well as information about the browser, such as which documents the user has visited, what other applets are running and so on.

The applet interface has been designed to prevent breaches of privacy.

Tcl Applet Execution

Applets are evaluated in a safe slave interpreter. See the interp(n) man page for details on the restrictions imposed upon scripts running in safe interpreters.

Applets are given access to the Tk toolkit via the Safe-Tk extension, which imposes some restrictions on the widgets provided by Tk. A toplevel widget is automatically created for the applet. The applet may refer to this window as the path '.'. The applet is also granted access to the browser window in which the applet was loaded. The applet embedwindow command is used to get a special pathname for this window. For an example see appinfo.tcl.

Any scripts for Tk widgets specified via -command style options are evaluated in the applet's safe interpreter. Unfortunately, it is not currently possible to specify variables for Tk widgets (such as for the -textvariable option) since variables cannot be accessed from other interpreters. This restriction will be removed in a future version of Tcl or Safe-Tk.

Clearing the Hyperwindow

When a hyperlink is activated that specifies an applet as the destination anchor the hyperpage is not automatically cleared. It is then up to the applet to clear the hyperpage page once it has commenced execution. This allows an applet to manipulate the document from which it is referenced (for example, eatdoc.tcl), or for applets to be loaded without affecting the current document if they are unrelated (a trivial example is example1.tcl). The applet may use the applet newpage command to clear the hyperpage if necessary.

Applet Scope and Longevity

The SurfIt! browser creates objects of four different types, as follows:
Browser
The browser itself of which there is only ever one. This object performs functions such as cache management, starting new hyperwindows and help.
Hyperwindows
A hyperwindow manages a single hyperpage. There may be an arbitrary number of hyperwindows existing at any time. These objects perform functions such as history navigation, stopping document loading, reloading and opening new hyperdocuments.
Hyperpages
Hyperpages display of one or more hyperdocuments.
Form level
The management of a HTML fill-in form, which is part of a hyperdocument. A hyperdocument may have an arbitrary number of forms.
Objects are arranged heirarchically, with the browser at the topmost level down to forms at the lowest level.

Applets are attached to one of the above types of objects. When an applet is initially loaded it is attached to the hyperpage which loaded it, unless the applet is loaded as an attribute of a form, in which case the applet is attached to that form instead. An applet may use the applet level command to change which object it is attached to. An example is eatdoc.tcl. For privacy reasons, applets may only attach to another object of a higher level.

When a hyperpage is cleared to load a new hyperdocument any applets currently attached to the hyperpage, or to any forms within that hyperpage, are destroyed. Any applets attached to a hyperwindow are destroyed when that object is destroyed. Applets attached at the browser level can only be destroyed either voluntarily by the applet itself or by the user via the browser 'Applet' menu.

The Applet Command

The applet interacts with the browser by using the applet command. The following methods are defined:
applet browserversion
returns a string describing the browser in which the applet is running. For example, SurfIt! 0.4alpha. An example of its use is appinfo.tcl.
applet embedwindow
returns a string which the applet may use to refer to the hyperwindow from which the applet was loaded. For an example see eatdoc.tcl.
applet embedindex
returns the index in the Text widget at which the applet was embedded. For applets attached to a form this is the beginning of the form. For an example see appinfo.tcl.
applet flush URL
flushes the hyperdocument URL from the browser's cache. For an example see autopilot.tcl.
applet formendindex
returns the index of the last character that is part of the form.
If the applet is not attached to a form then an error occurs.
applet formitems
If the applet is attached to a form then this command returns a list specifying the input items contained within the form. The list is of the form: {{type path} ...} where type is a valid type for <INPUT> elements, select or textarea for the <SELECT> and <TEXTAREA> elements respectively. path is the pathname of the Tk widget which handles input for that element, or an empty string if the input element is a hidden type.
If the applet is not attached to a form then an error occurs.

The applet is also notified when form items are created via the HMapplet_item callin.

applet level ?level?
with no arguments returns the level at which the applet is attached. May be one of form, hyperpage, hyperwindow or browser. If an argument is supplied then the applet is reattached at the given level. Applets are only allowed to promote themselves; they may not change to more specific levels. An applet attached at the form level may not change to another level.
Returns an empty string.
applet loaddata url data callback
asynchronously loads the data referred to by url. data is the name of a global variable into which the data is copied once the data transfer has been completed. callback is evaluated in the applet's interpreter when the data transfer has been completed - this is useful since the data may be read incrementally, hence tracing the data variable is not sufficient to determine when the data transfer is finished.

SurfIt! provides visual feedback to the user to indicate that data is being transferred. It is important for the user to be aware of the actions of the applet in case a malicious applet attempts to abuse network resources.

applet loadurl url ?type?
loads the URL url into the hyperwindow to which the applet is attached. If type is specified then the document will be rendered as the given MIME type.
Returns an empty string.
applet newpage
clears the applet's hyperpage in readiness to render a new document. Applets attached at the form level may not clear the hyperpage.
Returns an empty string.
applet parsehtml html
renders the HTML-formatted text given as html in the hyperpage to which the applet is attached. The new text is appended to the page's current contents.
Returns an empty string.
SurfIt! also defines the following commands in addition to those defined in a normal safe interpreter:
exit ?code?
causes the applet's interpreter to be deleted, and the associated toplevel to be destroyed. Note that destroy . has the same effect; if the applet does not require its own toplevel window then it should use wm withdraw . instead.
puts ?filed? text
writes the string given by text to the file descriptor given by filed. stdout is used by default, and only stdout or stderr are allowed. The string is prepended by which applet is outputing the string, to ensure that the user can distinguish the output of applets from the browser.
Commands provided by extensions may also be defined for the convenience of the applet. See the documentation for those extensions for usage. Note that the extension may not necessarily be loaded into the browser's interpreter, so the applet should take care as an error will result if the command is undefined. This list is subject to change.
getclock convertclock fmtclock random
These are from Extended Tcl.
blt_table
This is from the BLT extension.

Applet Callins

The browser also interacts with the applet by means on callins. Callins are procedures which are invoked by the browser in the applet's interpreter under certain circumstances. The following callins are defined:
terminate
This procedure is invoked when the applet is about to be destroyed due to the object it is attached to being destroyed.
formready
If an applet is attached to a form this procedure will be invoked after the form has been rendered.
HMsubmit_form method query
If the applet is attached to a form then this procedure is invoked when the form is submitted, but prior to the query being dispatched to the server. The applet then has the opportunity to modify the query. The return result of this procedure will be what is actually sent as the query, see below for correct format. If the procedure results in an error then the form submission is cancelled.

method is the form method by which the query is being sent to the server, and may be one of GET or PUT.

query is a Tcl list describing the query that is to be sent. The list is of the form {name1 value1 name2 value2 ...}. This list is mapped to the application/x-url-www-encoded form name1=value1&name2=value2&...

HMapplet_item type name value item
If the applet is attached to a form then this procedure is invoked for each input item in the form.

type is the type of the input item and may be any of the valid types for HTML <INPUT> items.

name is the name attribute given to the input item.

value is the input item's initial value, if any.

item is the pathname for the widget heirarchy which interacts with the user for this input item. The widget class will depend on the input item type. Hidden-type input items never have a widget associated with them.

anchor_activation url
If defined, this procedure is called whenever a source anchor is activated. url gives the destination anchor. NB. applets attached to forms should be notified of anchor activations within the form they are attached to, but this is not currently implemented.
Applets attached at the browser level do not receive these notifications.
pageloaded
If defined, this procedure is invoked whenever a new page has been loaded into the hyperwindow. This is generally only useful for applets attached at the hyperwindow level, since applets attached at a lower level would have been terminated during the loading process.
Applets attached at the browser level do not receive these notifications.

Applet Security

All possible care has been taken to prevent applets from accessing the user's environment. However, not all possible attacks have been tested. Some "Denial-Of-Service" attacks are prevented, such as an applet attempting to continuously clear the X selection so that no other application can cut and paste.

However, the current implementation of Tcl does not prevent "denial-of-service" attacks against SurfIt! itself - ie. an attack to prevent the browser from being usable. While I don't want to make things easy for nasty people, it is so easy to hang the browser that I thought I'd better warn legitimate applet developers to take care when writing applets. The problem is that applet scripts are evaluated synchronously by the (trusted) master interpreter which means that if an applet script never finishes then the browser will never regain the flow of control, thereby hanging the browser. The script while {1} {} is quite enough to achieve this effect.

If such an attack occurs (either maliciously or by accident) then the only recourse is to kill the SurfIt! process :-( . Future versions of Tcl will implement resource usage constraints which will be used to solve this problem.


applets.html,v 1.3 1995/11/17 03:30:51 steve Exp

Author: Steve Ball