SVG 1.2 - 27 October 2004

Previous | Top | Next

16 Events and Scripting

16.1 The script element

A script element is a place for executable content (e.g., ECMAScript or Java JAR file). Executable content can come either in the form of a script (textual code) or in the form of compiled code. If the code is textual, it can either be placed inline in the script element (as character data) or as an external resource, referenced through xlink:href attribute. Compiled code must be an external resource.

Scripting languages (such as ECMAScript) that have a notion of a "global scope" or a "global object" must have a single global object associated with the document (unique for each DOM Document node). This object is shared by all elements. Thus, an ECMAScript function defined within any script is in the "global" scope of the entire document in which the script occured. The global object must have all the methods and attributes from the SVGGlobal interface. It can be obtained from an SVG document through the SVGDocument::global attribute. Event listeners attached through event attributes and handler elements are also evaluated using the global scope of the document in which such a listener is defined.

For compiled languages (such as Java) that don't have a notion of "global scope", each script element, in effect, provides a separate scope object per script element. This scope object performs an initialization and serves as event listener factory for the handler element.

Script execution happens only at load time. Removing, inserting or altering script elements once the document has been loaded has no effect.

Exact details on how this element works depend on the executable content's type (either the resource MIME type or specified as an attribute). The SVG specification defines the behavior for two specific script types:

text/ecmascript

This type of executable content must be source code for the ECMAScript programming language (Ed 3 compact profile ES 327). This code is executed in the context of this element's owner document's global scope as explained above.

Also, the script global object can implement the EventListenerInitializer2 interface (described below) by providing an initializeEventListeners function that is called for every script element in the document and a createEventListener function that is called for every handler element that has a scriptContentType of "text/ecmascript".

SVG implementations that load external resources through protocols (such as HTTP) that support transfer encoding, must accept external script files with gzip compression ("Transfer-Encoding: gzip" for HTTP).

application/java-archive

This type of executable content must be an external resource that contains a Java Jar archive. The manifest file in the Jar archive must have an entry named SVG-Handler-Class. The entry's value must be a fully-qualified Java class name for a class contained in this archive. The user agent must instantiate the class from the Jar file and attempt to cast it to the EventListenerInitializer2 interface (defined below). If that fails, it should cast it to the deprecated EventListenerInitializer interface (for SVG 1.1 compatibility). Then the initializeEventListeners method should be called (both interfaces has this method) with the script element itself (for EventListenerInitializer2) or its owner document (for EventListenerInitializer) as a parameter. If a class listed in SVG-Handler-Class implements neither EventListenerInitializer nor EventListenerInitializer2, it is an error.

Note that the user agent can reuse classes loaded from the same URL, so the code must not assume that every script element or every document will create its own separate class object. Thus, one cannot assume, for instance, that static fields in the class are private to a document.

Other language bindings are encouraged to adopt one of the two strategies described above.

16.2 The handler element

The handler element is a convenient way to attach and detach event listeners to XML elements. It is based on XML Events.

SVG 1.2 makes the following modifications to XML Events:

handler Schema

  <define name='handler'>
    <element name='handler'>
      <ref name='attlist.handler'/>
      <ref name='SVG.handler.content'/>
    </element>
  </define>

  <define name='attlist.handler' combine='interleave'>
    <ref name='SVG.Core.attrib'/>
    <attribute name='ev:event' svg:animatable='false' svg:inheritable='false'>
      <choice>
        <data type='NMTOKEN'/>
        <data type='QName'/>
      </choice>
    </attribute>
    <attribute name='type' svg:animatable='false' svg:inheritable='false'>
      <ref name='ContentType.datatype'/>
    </attribute>
  </define>

  <define name='SVG.handler.content'>
    <choice>
      <group>
        <ref name='SVG.XLinkRequired.attrib'/>
      </group>
      <text/>
    </choice>
  </define>
scriptContentType

Specifies the scripting language that will be used to create a listener (see the above definition in script for possible values of this attribute). This attribute is mutally exclusive with xlink:href.

xlink:href

Specifies the script element that will be used to create a listener. This attribute is mutually exclusive with scriptContentType.

During the document's loading time (or when a handler element is inserted in the tree after the document has been loaded), the user agent creates an event listener object for each handler element. This is done by locating an appropriate EventListenerInitializer2 object and calling the createEventListener method on it. If the xlink:href attribute is used it must point to a local script element. In this case scope object associated with that script element is used. If the scriptContentType attribute is used then the document's global scope for that script type is used. It is an error to specify script types that inherently don't have global scope objects (e.g. "application/java-archive"). If neither xlink:href nor scriptContentType are specified, the document's value for scriptContentType is used. For the case of ECMAScript, if createEventListener function is not found in global scope, the following pseudo-code is used:

function createEventListener( node )
{
 var body = getTextData(node); // concatenated text from all text, cdata and entity reference children
 return document.global.eval("function(evt){" + body + "}")
}

Other scripting lanuage bindings are encouraged to provide similar default behavior.

Once a listener is created it is attached to appropriate event targets according to XMLEvents specification. If the handler element is removed, the corresponding event listener is removed from its targets. If the handler element is inserted into the tree again, the same event listener is reused. If the handler element's attributes or children are modified, the corresponding listener is removed from its targets, and a new listener is created and added back to the targets.

NOTE:

In the Java environment one would typically place data that is needed to create an event listener either as handler element's inline character data, as a custom attribute (say my:name attribute) or as custom markup inside the handler element. createEventListener then can read this information since the handler element is passed to it as a parameter.

16.3 DOM Interfaces

The EventListenerInitializer2 parameters are expressed purely in Core W3C DOM types. This is done so that this definition is reusable for other mark-up languages.

interface EventListenerInitializer
{
  void initializeEventListeners( in SVGDocument doc);
}

interface EventListenerInitializer2
{
  void initializeEventListeners( in dom::Element scriptElement );
  events::EventListener createEventListener( in dom::Element handlerElement );
}

16.4 Processing order for user interface event

The following is a replacement for section 16.5 in SVG 1.1.

The processing order for user interface events is as follows:

Various elements in SVG create shadow content which can be the target of user interface events. The following is a list of elements that can create shadow content which can be the target of user interface events:

For these situations, user interface events within the shadow content participate in the processing of user interface events in the same manner as if the shadow content were part of the main document. In other words, if shadow content contains a graphics element that renders above other content at the current pointer location, then it represents the topmost graphics element and will receive the pointer events before other elements. In this case, the user interface events bubble up through the target's ancestors, and then across the document border into the referencing element, and then through the ancestors of the referencing element. This process continues as necessary if there are multiple levels of nested shadow trees.