W3C

Scalable Vector Graphics (SVG) 1.2

W3C Working Draft 15 July 2003

This version:
http://www.w3.org/TR/2003/WD-SVG12-20030715/
Previous version:
http://www.w3.org/TR/2003/WD-SVG12-20030429/
Latest version:
http://www.w3.org/TR/SVG12/
Editor:
Dean Jackson, W3C, <dean@w3.org>
Authors:
See Author List

Abstract

This document specifies version 1.2 of the Scalable Vector Graphics (SVG) Language, a modularized language for describing two-dimensional vector and mixed vector/raster graphics in XML.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. The latest status of this document series is maintained at the W3C.

This document is the third public working draft of the SVG 1.2 specification. It lists the potential areas of new work in version 1.2 of SVG and is not a complete language description. In some cases, the descriptions in this document are incomplete and simply show the current thoughts of the SVG Working Group on the feature. This document should in no way be considered stable. This version does not include the implementations of SVG 1.2 in either DTD or XML Schema form. Those will be included in subsequent versions, once the content of the SVG 1.2 language stabilizes. This document references a draft RelaxNG schema for SVG 1.1.

This document has been produced by the W3C SVG Working Group as part of the W3C Graphics Activity within the Interaction Domain.

We explicitly invite comments on this specification. Please send them to www-svg@w3.org: the public email list for issues related to vector graphics on the Web. This list is archived and acceptance of this archiving policy is requested automatically upon first post. To subscribe to this list send an email to www-svg-request@w3.org with the word subscribe in the subject line.

The latest information regarding patent disclosures related to this document is available on the Web. As of this publication, the SVG Working Group are not aware of any royalty-bearing patents they believe to be essential to SVG.

Publication of this document does not imply endorsement by the W3C membership. A list of current W3C Recommendations and other technical documents can be found at http://www.w3.org/TR/. W3C publications may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite a W3C Working Draft as anything other than a work in progress."


Table of Contents


1 How to read this document and give feedback

This draft of SVG 1.2 is a snapshot of a work-in-progress. The SVG Working Group believe the most of the features here are complete and stable enough for implementors to begin work and provide feedback. Some features already have multiple implementations.

This is not a complete specification of the SVG 1.2 language. Rather it is a list of features that are under consideration for SVG 1.2. In many cases the reader will have to be familiar with the SVG 1.1 language.

The main purpose of this document is to encourage public feedback. The best way to give feedback is by sending an email to www-svg@w3.org. Please include some kind of keyword that identifies the area of the specification the comment is referring to in the subject line of your message (e.g "1.2 compositing" or "1.2 audio and video formats"). If you have comments on multiple areas of this document, then it is probably best to split those comments into multiple messages.

The public are welcome to comment on any aspect in this document, but there are a few areas in which the SVG Working Group are explicitly requesting feedback. These areas are noted in place within this document. There are also a few areas related to the specification that are listed here:

The SVG Working Group appreciate the many comments it received on the previous SVG 1.2 working draft. Some of these comments have been addressed and this draft includes the resolution. Unfortunately many of the comments have yet to be addressed by the group as it spent a large amount of time discussing the work in progress at the publication of the previous draft. Each comment has been recorded and will be discussed in time. Please keep them coming, and do not be discouraged if there has not yet been a response to your previous comment.

2 Text Wrapping

SVG 1.2 enables a block of text to be rendered inside a shape, while automatically wrapping the text into lines, using the flowText element. The idea is to mirror, as far as practical, the existing SVG text elements.

2.1 The flowText element

The flowText element specifies a block of text to be rendered. It contains at least one flowRegion element, defining regions in which the child flowDiv element of the flowText should be flowed into.

The following is a extract of an XML Schema that describes the flowText element.

<xs:element name="flowText">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="flowRegion"/>
      <xs:element ref="flowRegionExclude"/>
      <xs:element ref="flowDiv"/>
    </xs:sequence>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.2 The flowRegion element

The flowRegion element contains a set of shapes and exclusion regions in which the text content of a parent flowText element is drawn into. A flowRegion element has basic shapes and path elements as children, as well as a flowRegionExclude element. The children of a flowRegion element are inserted into the rendering tree before the text is drawn, and have the same rendering behavior as if they were children of a g element.

The child elements create a sequence of shapes in which the text content for the parent flowText will be drawn into. Once the text fills a shape it flows into the next shape. The flowRegionExclude child describes a set of regions in which text will not be drawn into, such as a cutout from a rectangular block of text.

The child elements of a flowRegion can be transformed as usual, but the text is always laid out in the coordinate system of the flowText element. For example, a rect child with a 45 degree rotation transformation will appear as a diamond, but the text will be axis aligned.

The following is a extract of an XML Schema that describes the flowRegion element.

<xs:element name="flowRegion">
  <xs:complexType>
    <xs:sequence>
      <xs:choice>
        <xs:group ref="ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
        <xs:group ref="flowRegionExclude" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>     

2.3 The flowRegionExclude element

The flowRegionExclude element contains a set of shapes defining regions in which flowed text is not drawn. It can be used to create exclusion regions from within a region of text.

If flowRegionExclude is a child of a flowRegion then it describes an exclusion region for that particular flowRegion. If it is a child of flowText then it describes exclusion regions for all flowRegion children of the flowText.

The following is a extract of an XML Schema that describes the flowRegionExclude element.

<xs:element name="flowRegionExclude">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="ShapeElements" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>     

2.4 The flowDiv element

The flowDiv element specifies a block of text to be inserted into the text layout, and marks it as a division of related text. The children of the flowDiv element will be rendered as a block: offset before and after from their parent's siblings. By separating the logical order of text (in successive flowDiv elements) from the physical layout (in regions, which can be presented anywhere on the canvas) the SVG document structure encourages creation of a default, meaningful linear reading order while preserving artistic freedom for layout. This enhances accessibility.

The following is a extract of an XML Schema that describes the flowtext element.

<xs:element name="flowDiv">
  <xs:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="flowPara"/>
      <xs:element ref="flowRegionBreak"/>
    </xs:choice>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.5 The flowPara element

The flowPara element marks a block of text as a logical paragraph.

The following is a extract of an XML Schema that describes the flowPara element.

<xs:element name="flowPara">
  <xs:complexType mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="flowRegionBreak"/>
      <xs:element ref="flowLine"/>
      <xs:element ref="flowTref"/>
      <xs:element ref="flowSpan"/>
    </xs:choice>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.6 The flowSpan element

The flowSpan element specifies a block of text to be rendered inline, and marks the text as a related span of words. The flowSpan element is typically used to allow a subset of the text block, of which it is a child, to be rendered in a different style, or to mark it as being in a different language.

The following is a extract of an XML Schema that describes the flowSpan element.

<xs:element name="flowSpan">
  <xs:complexType mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="flowSpan"/>
      <xs:element ref="flowLine"/>
      <xs:element ref="flowRegionBreak"/>
    </xs:choice>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.7 The flowRegionBreak element

When the flowRegionBreak element is inserted into the text stream it causes the text to stop flowing into the current region at that point. The text after the flowRegionBreak element begins in the next region. If there is no next region, then the text will stop being rendered at the point of the flowRegionBreak.

The following is a extract of an XML Schema that describes the flowRegionBreak element.

<xs:element name="flowRegionBreak">
  <xs:complexType/>
</xs:element>     

2.8 The flowLine element

The flowLine element is used to force a line break in the text flow. The content following the end of a flowLine element will be placed on the next available strip in the flowRegion that does not already contain text. This happens even if the flowLine element has no children.

Note that if there are no printing characters between the end of multiple flowLine elements the second and greater flowLine elements have no effect as the current line does not contain any text when they are processed.

In all other aspects, the flowLine element is functionally equivalent to the flowSpan element.

The following is a extract of an XML Schema that describes the flowLine element.

<xs:element name="flowLine">
  <xs:complexType mixed="true">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element ref="flowSpan"/>
      <xs:element ref="flowLine"/>
      <xs:element ref="flowRegionBreak"/>
    </xs:choice>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.9 The flowTref element

The flowTref element is used to insert the child text content of a referenced element. It's effect is analogous to the tref element.

The following is a extract of an XML Schema that describes the flowTref element.

<xs:element name="flowTref">
  <xs:complexType>
    <xs:attribute ref="href" use="required"
        namespace="http://www.w3.org/1999/xlink"/>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.10 The flowRef element

The flowRef element references a flowRegionElement. It causes the referenced element's geometry to be drawn in the current user coordinate system along with the text that was flowed into the region.

The following is a extract of an XML Schema that describes the flowRef element.

<xs:element name="flowRef">
  <xs:complexType>
    <xs:attribute ref="href" use="required"
        namespace="http://www.w3.org/1999/xlink"/>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
  </xs:complexType>
</xs:element>     

2.11 Text Flow

Text flow is defined as a post processing step to the standard text layout model of SVG. At a high level the steps for flowing text are as follows:

  1. The text is then processed in logical order to determine line breaking opportunities between characters, according to Unicode Standard Annex No. 14
  2. Text layout is performed as normal, on one infinitely long line, soft hyphens are included in the line. The result is a set of positioned Glyphs.
  3. Glyphs are associated with the word who's characters generated it. In cases where characters from multiple words contribute to the same glyph the words are merged and all the glyphs are treated as part of the earliest word in logical order.
  4. The glyphs from a word are collapsed into Glyph Groups. A Glyph Group is comprised of all consecutive glyphs from the same word. In most cases each word generates one glyph group however in some cases the interaction between BIDI and special markup may cause glyphs from one word to have glyphs from other words embedded in it.
  5. Each Glyph Group has two extents calculated: is it's normal extent, and it's last in text region extent. It's normal extent is the sum of the advances of all glyphs in the group except soft hyphens. The normal extent is the extent used when a Glyph Group from a later word is in the same text region. The last in text region extent includes the advance of a trailing soft hyphens but does not include the advance of trailing whitespace or combining marks (ABC width?). The last in text region extent is used when this glyph group is from the last word (in logical order) in this text region.
  6. The location of the first strip is determined based on the first word in logical order (see Calculating Text Regions and determining strip location).
  7. Words are added to the current Strip in logical order. All the Glyph Groups from a word must be in the same strip and all the glyphs from a Glyph Group must be in the same Text Region.

    When a word is added the line height may increase, it can never decrease from the first word. An increase in the line height can only reduce the space available for text placement in the span.

    The span will have the maximum possible number of words.

  8. The Glyphs from the Glyph Groups are then collapsed into the text regions by placing the first selected glyph (in display order) at the start of the text region and each subsequent glyph at the location of the glyph following the preceding selected glyph (in display order).
  9. The next word is selected and the next strip location is determined. Goto Step 7.

2.12 Determining Strip Location

To determine the placement of a strip the Glyph Groups from first word is used. The initial position for the strip is calculated, taking into account the end (in non text progression direction) of the previous strip and the appropriate margin properties.

The line-box is calculated using the initial position as the top/right edge of the line-box, and the line-height of the first word. The 'bottom/right' edge of the line-box must be checked against the margin properties, if it lies within the margin then processing moves to the next flow region.

Once the line-box is calculated the Strip and it's associated Text Regions are calculated (see: Calculating Text Regions). If the first word can be placed in the text regions of this Strip then this location is used for the next line of text. If the first word does not fit then the top/right edge is shifted by 'line-advance' and the new line-box is checked. This proceeds until the word fits or end of the flow region is reached at which point processing moves to the next flow region.

2.13 Calculating Text Regions

In order to flow text into arbitrary regions it is necessary to calculate what areas of the arbitrary region are available for text placement. SVG uses a fairly simple algorithm to do this.

In summary you intersect the flow region geometry with the current line-box. The result of this intersection is referred to as the strip. The strip is then split into text regions where ever a piece of geometry from the flow region 'intrudes'. It is important to ignore edges & points that are co-incident with the top or bottom of the line-box.

The diagram below shows the text strips used on a given shape.

image describing the location of text strips

The following is the algorithm with more detail:

The current flow region and any applicable exclude regions must be combined into one piece of geometry, simply concatenating the geometry is sufficient as this entire algorithm deals simply with segments of the paths and does not use directionality information until the inclusion tests at the end. The result of the concatenation of the geometry is referred to as the flow geometry.

Next the line-box is calculated, from the top/right edge of the line, the line-height and the bounding box of the flow region. This line-box is intersection with the flow geometry, clipping the flow geometry segments to the line box.

The bounding box is then calculated separately for each of the segments in the intersection.

The left and right (top and bottom respectively for vertical text) edges of the bounding boxes are sorted in increasing coordinate order (x for horizontal text, y for vertical text), for edges at the same location the left/top (or opening) edge is considered less than right/bottom (or closing) edges. The following pseudo code then generates the list of open areas for the current line:

        Edge [] segs = ...; // The sorted list of edges.

        Edge edge = segs[0];
        int count = 1;
        double start = 0;
        for (i=1; i<segs.length; i++) {
            edge = segs[i];
            if (edge.open) { 
              // 'open' is true, this is the start of a block out region.
                if (count == 0) {
                    // End of an open region so record it.
                    rgns.add(new TextRegion(start, edge.loc));
                }
                count++;
            } else {
              // 'open' is false, this edge is the end of a block out region.
                count--;
                if (count == 0) {
                    // start of an open area remember it.
                    start = edge.loc;
                }
            }
        } 

This gives the regions of the strip that are unobstructed by any flow geometry (from either exclusion or flow regions), however those regions may be outside the flow region (such as in a hole, such as the middle of an 'O'), or inside an exclusion region. Thus the center of each rectangle should be checked first to see if it lies inside any exclusion region if so the rectangle is removed from the list. Second it must be checked for inclusion in the flow region, if it is inside the flow region then the rectangle is available for text placement and becomes a text region for the current strip.

Once all the text regions for a strip are located left and right Margins for horizontal text (top and bottom margins for vertical) as well as indent are applied. Margins are applied to each text region. For the first span in a paragraph (flowPara for flowRegionBreak) the indent is added to the appropriate margin of the first text region. For left to right text this is the left margin of the left most text region, for right to left text this is the right margin of the right most text region, and for vertical text is the top margin of the top most text region.

this is applying margins to every Text Region we could just apply them to the first/last text regions. Perhaps have a separate property for 'internal' margins and the 'external' margins?.

If the left/right (top/bottom) edges of a text region pass each other due to the application of margins (or indent) the text region is removed from the list. If the text region removed had indent applied the indent is not applied to the next text region in text progression direction it is simply ignored.

We could have the indent move but it isn't clear that this would always be correct. The above is simpler and for the cases where indent is most commonly used, simple rectangles, it doesn't matter.

Should we restrict indent's range such that it can be no more negative than the margin it is applied to? Our feeling is no. If the user wants to shift the boxes out they should be able to - the only complication this adds is that the geometry may no longer define the bounding box of the text.

3 Rendering Custom Content

3.1 Introduction

Many of the enhancements to the SVG language are based on using SVG as a presentation layer for structured data (e.g. XForms). Public feedback has also suggested that many content developers are using SVG as the graphical user interface to their XML data, either through declarative transformations such as XSLT or through scripting (loading XML data into the SVG User Agent and transforming using the DOM).

While it is already possible in SVG 1.0 to use scripting to transform XML from a private namespace into SVG, the code has to be replicated in each SVG file and modified for each namespace. The SVG Working Group is investigating approaches to see whether new features might be added to SVG 1.2 in order to better facilitate these techniques. This section summarizes the current status of these investigations within the Working Group, describes target use cases, proposed design requirements, discussion of some of the approaches that are being considered, and a list of some of the open issues.

The Rendering Custom Content (RCC) approach is based on a formalization and unification of the shadow tree approach which already exists in various ways within SVG 1.0/1.1, where particular features such as the use, pattern and marker elements required a rendering tree which differs from the original document tree. With RCC, all non-SVG elements are given an optional "shadow DOM tree". For backwards compatibility with SVG 1.0/1.1, by default the shadow trees are empty. However, if RCC is used, then certain non-SVG elements can have a shadow tree which represents the rendering and interactive behavior for that particular custom element using SVG content within the shadow tree, thus allowing custom elements (i.e., non-SVG elements) to get rendered because the Original XML for the custom elements has a corresponding Generated Alternative SVG within the a shadow tree which defines its rendering and behavior.

The working group is looking into opportunities for unification and simplification of the specification of many existing language features based on the RCC proposal, but these exercises are in their early stages.

The current RCC proposal focuses primarily on low-level, foundation technology and relies on scripting for all but the most trivial transformations. It may be possible to provide more support for a declarative syntax, similar to, or using parts of, XSLT. Some existing difficulties with XSLT include:

The "Rendering Custom Content" feature is sometimes referred to as "RCC" below.

Example rcc01 below provides a simple example of the Rendering Custom Content feature. In the example, the SVG file references a set of custom elements for flowcharting using the extensionDefs element, and then uses the custom elements to draw the flowchart. Note that the document below is semantically more meaningful due to the use of the custom elements than it would have been if the file had contained just the low-level visual presentation elements (i.e., circle, rect, path and text):

<svg width="12cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.2">
  <desc>Example rcc01 - simple flowchart example using RCC</desc>

  <!-- XPointer reference to the location for the flowchart extensions -->
  <extensionDefs xlink:href="rcc01-flowchart-exts.svg#flowcharts"/>

  <!-- Use the flowchart extensions. As a result of using the extensions,
       a shadow tree of low-level SVG (circle, rect, path elements)
       is added to the SVG DOM. The user agent renders the shadow tree. -->
  <flowchart xmlns="http://example.org/rcc-flowcharts"
             x="0%" y="0%" width="100%" height="100%">
    <terminalNode>Start</terminalNode>
    <processNode>Step 1</processNode>
    <processNode>Step 2</processNode>
    <terminalNode>End</terminalNode>
  </flowchart>
</svg> 

Example rcc01 - of rendering arbitrary content

View this image as SVG (SVG-enabled browsers only)

Here is the file which defines the simple flowcharting extensions used in the example above:

<svg xmlns="http://www.w3.org/2000/svg" version="1.2"
     xmlns:ev="http://www.w3.org/2001/xml-events">
  <desc>Supplemental file for example rcc01.svg - 
        contains definition of simple flowchart extension elements.</desc>

  <extensionDefs id="flowcharts" namespace="http://example.org/rcc-flowcharts">

    <!-- Example needs to be upgraded to show handling of mutation events -->

    <defs>
      <symbol id="connectorline">
        <path transform="translate(0 50)" stroke="black" stroke-width="3" fill="black"
              d="M 0,0 L 90,0 L 90,-10 L 100,0 L 90,10 L 90,0"/>
      </symbol>
    </defs>

    <elementDef name="terminalNode">
      <prototype>
        <g>
          <circle stroke="#008" stroke-width="5"  fill="none" cx="50" cy="50" r="50"/>
          <text x="50" y="57" font-size="25" text-anchor="middle"><refContent/></text>
        </g>
      </prototype>
    </elementDef>

    <elementDef name="processNode">
      <prototype>
        <g>
          <rect stroke="#080" stroke-width="5" fill="none" width="150" height="100" rx="10"/>
          <text x="75" y="57" font-size="25" text-anchor="middle"><refContent/></text>
        </g>
      </prototype>
    </elementDef>

    <elementDef name="flowchart">
      <prototype>
        <svg><refContent/></svg>
      </prototype>
      <script ev:event="SVGBindEnd" type="text/ecmascript"><![CDATA[
        svgns = "http://www.w3.org/2000/svg";
        xlinkns = "http://www.w3.org/1999/xlink";
        flowchartns = "http://example.org/rcc-flowcharts";
        ELEMENT_NODE = 1;
        SIDE_INDENT = 50;
        PROCESSNODE_WIDTH = 150;
        TERMINALNODE_WIDTH = 100;
        CONNECTOR_WIDTH = 100;
        YPOS = 50;
        var flowchartelement = evt.target;
        var ap = flowchartelement.shadowTree;
        var svgElm = ap.firstChild;
        svgElm.setAttributeNS(NULL, "x", flowchartelement.getAttribute("x"));
        svgElm.setAttributeNS(NULL, "y", flowchartelement.getAttribute("y"));
        svgElm.setAttributeNS(NULL, "width", flowchartelement.getAttribute("width"));
        svgElm.setAttributeNS(NULL, "height", flowchartelement.getAttribute("height"));

        // Determine total width needed and set viewBox attribute appropriately.
        var totalWidth = 0;
        var nodeCount = 0;
        for( var node = flowchartelement.firstChild ; node != null ; node = node.nextSibling )
        {
          // only process elements in flowchart ns
          if( node.nodeType == ELEMENT_NODE && node.namespaceURI == flowchartns) {
            nodeCount++;
            if (node.localName == "processNode")
              totalWidth += PROCESSNODE_WIDTH;
            else if (node.localName == "terminalNode")
              totalWidth += TERMINALNODE_WIDTH;
          }
        }
        totalWidth += (nodeCount-1)*CONNECTOR_WIDTH + 2*SIDE_INDENT;
        svgElm.setAttributeNS(NULL, "viewBox", "0 0 "+totalWidth+" 200");
        var xtrans = 50;

        // Position all of the nodes and draw the connectors.
        var xpos = SIDE_INDENT;
        var nodeNum = 0;
        for( var node = flowchartelement.firstChild ; node != null ; node = node.nextSibling )
        {
          // only process elements in flowchart ns
          if( node.nodeType == ELEMENT_NODE && node.namespaceURI == flowchartns) {
            node.shadowTree.setAttributeNS(NULL, "transform", "translate("+xpos+" "+YPOS+")");
            var nodeWidth;
            if (node.localName == "processNode") {
              nodeWidth = PROCESSNODE_WIDTH;
            } else if (node.localName == "terminalNode") {
              nodeWidth = TERMINALNODE_WIDTH;
            }
            xpos += nodeWidth;
            // Add connector line to end of flowchart node's shadowTree.
            if (nodeNum < (nodeCount-1)) {
              var useElement = document.createElementNS(svgns, "use");
              useElement.setAttributeNS(xlinkns, "xlink:href", "#connectorline");
              useElement.setAttributeNS(NULL, "transform", "translate("+nodeWidth+" 0)");
              node.shadowTree.appendChild(useElement);
              xpos += CONNECTOR_WIDTH;
            }
            nodeNum++;
          }
        }
      ]]></script>
    </elementDef>

  </extensionDefs>

</svg> 

3.2 Use Cases

3.2.1 Transforming semantically-rich XML to presentation-rich SVG

One topic that came up repeatedly at SVG Open 2002 is strategies for relating semantically rich XML markup, such as GML features, with the presentation-oriented nature of SVG. Some presentations at SVG Open called on the community to architect their documents in terms of model-view-controller and argued the SVG tag set represents the "view" part of MVC. Others described the need to look at geographical markup such as GML as "data" and the corresponding SVG as "presentation", and suggested that the transformation from GML into SVG represents a styling operation. Much of the open discussion at the conference talked about how to map semantically rich user interface (UI) tagsets such as XForms UI elements into SVG.

Example rcc-gml-01 below takes sample code from section 4.6 from the Geography Markup Language (GML) specification, version 2.1.2. The 'extensionDefs' element would effect a client-side transformation from original XML/GML into final-form SVG rendering. A key value with RCC in this circumstance is that the GML content is preserved without modification, thereby allowing a smart client ultimate presentation flexibility for displaying any aspect of the information within the main drawing area (e.g., as text on the page or perhaps as tooltips) or displaying some of the information in separate frames, windows, panes or regions. User interface might be provided to let the user tell the GIS application what part of information he would like to see. (Note: in many cases for mapping applications, factors such as performance requirements might make server-side transformations a better option than RCC, which is a client-side transformation.)

<svg width="12cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.2">
  <desc>Example rcc-gml-01 - GML and RCC</desc>

  <!-- XPointer reference to the location for the GML extensions -->
  <extensionDefs xlink:href="rcc-gml-01-exts.svg#gml"/>

  <CityModel xmlns="http://www.opengis.net/examples"
             xmlns:gml="http://www.opengis.net/gml"
             xmlns:xlink="http://www.w3.org/1999/xlink"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.opengis.net/examples city.xsd">

    <gml:name>Cambridge</gml:name>
    <gml:boundedBy>
      <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
        <gml:coord><gml:X>0.0</gml:X><gml:Y>0.0</gml:Y></gml:coord>
        <gml:coord><gml:X>100.0</gml:X><gml:Y>100.0</gml:Y></gml:coord>
      </gml:Box>
    </gml:boundedBy>

    <cityMember>
      <River>
        <gml:description>The river that runs through Cambridge.</gml:description>
        <gml:name>Cam</gml:name>
        <gml:centerLineOf>
          <gml:LineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
            <gml:coord><gml:X>0</gml:X><gml:Y>50</gml:Y></gml:coord>
            <gml:coord><gml:X>70</gml:X><gml:Y>60</gml:Y></gml:coord>
            <gml:coord><gml:X>100</gml:X><gml:Y>50</gml:Y></gml:coord>
          </gml:LineString>
        </gml:centerLineOf>
      </River>
    </cityMember>

    <dateCreated>2000-11</dateCreated>
  </CityModel>
</svg> 

3.2.2 XForms and SVG

The charter of the SVG Working Group includes determining how to combine XForms and SVG. The new RCC features may help provide the foundation for allowing implementers to create combined SVG+XForms implementations.

Example rcc-ui-01 below takes sample code from [Appendix G of the XForms specification | http://www.w3.org/TR/xforms/sliceG.html ] . The extensionDefs element would effect a client-side transformation from original XForms elements into final-form SVG rendering. In this example, the assumption is that the extension would implement all or at least a large part of the XForms specification via DOM/scripting.

<svg width="12cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.2"
     xmlns:xforms="http://www.w3.org/2002/xforms/cr"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:ev="http://www.w3.org/2001/xml-events"
     xmlns:my="http://commerce.example.com/payment">
  <desc>Example rcc-xforms-01 - using RCC within a combined XForms+SVG user agent</desc>
  <title xml:lang="fr">XForms en SVG</title>

  <!-- XPointer reference to the location for the XForms extensions to SVG.
       The extensions convert the XForms UI elements into low-level SVG
       interactive graphics and also provide  high-level features,
       such as client-side validation and the XForms event model. -->
  <extensionDefs xlink:href="rcc-xforms-01-exts.svg#xforms"/>

  <rx:renderXForms xmlns:rx="http://example.org/rcc-xforms"
         xmlns="http://www.w3.org/2002/xforms/cr">

    <model schema="payschema.xsd">
      <instance>
        <my:payment as="credit">
          <my:cc />
          <my:exp />
        </my:payment>
      </instance>
      <submission action="http://www.example.com/buy.rb" method="post" id="s00" />
      <bind nodeset="my:cc" relevant="../@as='credit'" required="true()" />
      <bind nodeset="my:exp" relevant="../@as='credit'" required="true()" />
    </model>

    <group xmlns="http://www.w3.org/2002/xforms/cr">
      <trigger>
        <label>Francais</label>
        <toggle case="fr" ev:event="xforms-activate" />
      </trigger>
      <trigger>
        <label>English</label>
        <toggle case="en" ev:event="xforms-activate" />
      </trigger>
    </group>

    <input ref="my:cc">
      <label xml:lang="fr">Numero de carte bancaire</label>
      <alert xml:lang="fr">Saississez un numro de carte bancaire en cours
       (sparez par un espace ou un trait d'union chaque groupe de chiffres)</alert>
    </input>

    <input ref="my:exp">
      <label xml:lang="fr">Date d'chance</label>
    </input>

    <submit submission="s00">
      <label xml:lang="fr">Achetez</label>
    </submit>
</svg> 

3.2.3 UI widget support

A large part of the SVG developer community and the SVG Working Group believe that a top priority for SVG 1.2 is enhancements that allow for easier creation of custom user interface widgets. A particular technical approach for UI widgets is to leverage XForms in various ways.

The SVG Working Group have adopted the position that SVG 1.2 should first address the low-level foundation features necessary to support fully custom UI widgets that allow sophisticated developers to leverage SVG's power in the development of graphic user interfaces. At present, the SVG Working Group is against the approach of attempting to define a full user interface system, such as MFC or Java SWING, for SVG 1.2.

One of the motivations behind RCC is to define a small number of foundation features which can help address many of the low-level UI widget features demanded by the SVG developer community. In order to provide greater flexibility and expressive power, it might make sense to simultaneously add new utility methods in the SVG DOM, such as improvements in area of geometry queries (e.g., bounding box queries that take into account things such as stroke widths and filter effects).

Example rcc-ui-01 supplements the XForms example above with the following simple example which shows a set of extension elements ui:menubar, ui:menu, ui:menuitem) which present a menubar and a scrolling area for graphics.

<svg width="525" height="575"
     xmlns="http://www.w3.org/2000/svg" version="1.2"
     xmlns:ui="http://example.org/rcc-ui">
  <desc>Example rcc-ui-01 - using rcc for UI elements</desc>
  <title>UI in SVG</title>

  <!-- XPointer reference to the location for the UI extensions to SVG.
       The extensions convert the UI elements into low-level SVG. -->
  <extensionDefs xlink:href="rcc-ui-01-exts.svg#ui"/>

  <ui:menubar x="25" y="25" width="500" height="20" font-size="14">
    <ui:menu title=File>
      <ui:menuitem title=New op=newdoc(evt)>
      <ui:menuitem title=Open op=opendoc(evt)>
    </ui:menu>
    <ui:menu title=Edit>
      <ui:menuitem title=Copy op=copy(evt)>
      <ui:menuitem title=Past op=paste(evt)>
    </ui:menu>
  </ui:menubar>

  <ui:scrollArea x="25" y="50" width="500" height="400">
    <image xlink:href="..." ... />
    <path d="..." ... />
    <text transform="..." font-size="...">...</text>
  </ui:scrollArea>
</svg> 

3.2.4 More powerful use: reusable symbols, UI elements and components

One of the most common requests among SVG developers is to enhance SVG's symbol and use features to provide more flexibility. Symbols are used in many different applications of SVG, for example mapping. The use element satisfies some needs, but content creators have run into many shortcomings that force them to either abandon SVG or sacrifice the quality of the presentation or write large amounts of ECMAScript or Perl. Right now, each instance of a symbol is restricted to a simple clone-with-specified-properties operation, with the only possible difference between cloned instances coming from a different set of inherited properties (for example, one instance might inherit fill="blue" whereas another instance might inherit fill="red"). Many developers have requested the ability to create template objects which can be reused but where instances of the symbol can differ in arbitrary ways using more flexible parameterization techniques. One specific unsatisfied requirement of SVG 1.1 is the ability to define a symbol for a standard UI element such as a button and then change the text on each instance where the text is treated as an instance parameter . In the more complex case, the notion of "reusable symbols" moves into the realm of "reusable components". Examples of reusable components include business graphs, schematics, process flow diagrams, GANTT charts and organization charts. In the case of a business graph, the instance parameters might include the per-graph tabular data and some level of per-graph formatting control, such as graph title and titles for the axes. In the case of an organization chart, per-node instance data might reflect whether a given person is a permanent employee or a contractor, which might result in correspondingly different graphical representations.

RCC may provide a mechanism which meets many of the requirements for a more powerful use element by adding the notion of per-instance parameters. The graphical contents of the original symbol could be cloned into the shadow tree and then any instance-specific adjustments (e.g., different text on each different button) could be applied to each instance's shadow tree.

One thing to note is that RCC describes an entirely different mechanism than the use element. The use element works by reference, not by cloning. Thus, with use, there is only one copy of the symbol. With the shadow tree approach, each instance gets its own shadow tree. (Note: the refContent element (see below) provides a mechanism to eliminate some forms of unnecessary/undesirable cloning, often with the result of smaller memory requirements. Also, it is possible to put use elements in the shadow tree, which represents another mechanism for minimizing cloning.)

Example rcc-widgets-01 demonstrates how the RCC features can be used to provide more flexibility in defining reusable symbols than what is possible with the use element. The example shows the use of star and button extensions. The star extension offers three parameters: the coordinates of the star in the sky (which would probably get used to position the star onto the SVG canvas), the magnitude of the star (which might affect the scaling of the graphics — larger magnitude stars might draw larger) and the name of the star (which might get rendered beneath the picture of the star or be presented as a tooltip). The button extension also offers eight parameters: x, y, minimum width, maximum width, minimum height, maximum height, maximum lines of text within the button (a value of one means no text wrapping), and the text which should appear inside the button .

<svg width="12cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.2"
     xmlns:widg="http://example.org/rcc-widgets">
  <desc>Example rcc-widgets-01 - using RCC for reusable widgets</desc>
  <title>Widgets in SVG</title>

  <!-- XPointer reference to the location for the widgets extensions to SVG.
       The extensions convert the widget elements into low-level SVG. -->
  <extensionDefs xlink:href="rcc-widgets-01-exts.svg#widgets" />

  <widg:star coords="..." magnitude="-1.42">Sirius</widg:star>
  <widg:star coords="..." magnitude="-0.27">Alpha Centauri</widg:star> <widg:button x="200" y="400" 
               minWidth="50" maxWidth="200" minHeight="20" maxHeight="40"
               maxLines="2">Northern hemisphere stars</widg:button>
  <widg:button x="400" y="400" 
               minWidth="50" maxWidth="200" minHeight="20" maxHeight="40"
               maxLines="2">Southern hemisphere stars</widg:button> 
</svg> 

Example rcc-widgets-02 demonstrates higher-level custom elements which can act as containers for other elements. The first custom element below is a scrolling region custom element. The contents of the scrolling region is any combination of custom elements and SVG elements which are drawn within the region and which can be scrolled via manipulating a scrollbar which is automatically attached to the scrolling region. Inside the scrolling region is a second custom element, a bar chart. This custom element converts tabular graph data information into a shadow tree of rectangles, lines and text which draws out a bar chart. Note that the barchart and the text element below the bar chart will scroll together because both are children of the scrolling region custom element.

<svg width="12cm" height="3cm"
     xmlns="http://www.w3.org/2000/svg" version="1.2"
     xmlns:widg="http://example.org/rcc-widgets">
  <desc>Example rcc-widgets-02 - using RCC for container widgets</desc>
  <title>Container widgets in SVG</title>

  <!-- XPointer reference to the location for the widgets extensions to SVG.
       The extensions convert the widget elements into low-level SVG. -->
  <extensionDefs xlink:href="rcc-widgets-02-exts.svg#widgets" />

  <widg:scrollRegion x="25" y="25" width="150" height="150">

    <barchart xmlns="http://example.org/rcc-widgets">
      <data>
        <row><val>100</val><val>150</val></row>
        <row><val>125</val><val>119</val></row>
      </data>
      <format>
        <xaxis><label>Log of avg galaxy distance</label></xaxis>
        <yaxis><label>Overall brightness</label></yaxis>
      </format>
    </barchart>

    <text x="75" y="135" font-size="20">Information is courtesy of example.com</text>
  </widg:scrollRegion>

</svg> 

3.2.5 Graphical UI for Web Services

The traditional way of looking at the Web is from an end-user/client perspective. The end-user is the center of the universe and the entire Web exists out there to be accessed. However, there is an alternate viewpoint, which is the organization which wants to interact with other organizations and with people via the Web. For example, XYZ company looks at the Web as a means to communicate with its own computing resources, its partners computing resources, and its customers. Businesses these days are treating each of the interactions as a generic Web service, and the W3C and other standards organizations are rapidly providing the standards infrastructure for Web Services.

From the point of view of the IT department in a business, an interaction with a human should be treated exactly like an interaction with a computer. In fact, the IT team may sometimes get some information from an automated source such as a computer one day and find that it needs to get the same information the next day manually from a real person. Thus, it makes sense to treat each human-computer interaction as just another Web service.

When the Web service requires a human-computer interaction, the Web service will describe the interaction using various semantically-rich XML. However, this interaction needs to be "styled" into a human-computer interaction. Adding the ability for SVG to be able to visually render arbitrary XML enables SVG to be a key component in Web Services when a human-computer interaction is required. One application of this idea is to use SVG and XForms to populate a shadow tree within an otherwise semantically rich XML document.

An example is not available in this draft.

3.2.6 Adaptable content

The ability to specify a transformation from Original XML into Generated Alternative SVG would provide a clean, simple, and powerful way of creating content that could adjust based on the current client environment. Right now, client-side SVG has only limited ability to adjust based on the client environment, such as the media facility in CSS-enabled SVG implementations and the few test attributes defined in the SVG language (e.g., systemLanguage).

The ability to render arbitrary XML might provide more flexibility in the styling transformation, taking into account the nature of the client: color bit depth, screen size, screen resolution, zoom level, whether a Web connection exists, which version of SVG (1.0/1.1/1.2/2.0), which profile is supported (Full or Basic, for example) and possibly user preferences. Of course, any adaptability requires the transformation specification to test for various conditions in the client, which probably means additional DOM methods, additional test attributes, and possibly some sort of expression evaluation system. Thus, for RCC to have maximum usefulness in the area of adaptable content, there would need to be complementary facilities added to the SVG language for queries into the media features within the client environment. Such features might be added to a future version of the SVG language. Two options include the ability to query into CC/PP information (see Composite Capability/Preference Profiles (CC/PP): Structure and Vocabularies and incorporation of CSS3 Media Queries.

An example is not available in this draft.

3.2.7 Expression-based attribute values

Various SVG content developers have requested the ability to use expressions such as XPath within path data, for attribute values and for property values. One such use of expression-based attributes values requested by the community is to allow a path element to contain expressions, such as <path d=" M {viewport.left+10px}, {viewport.top+10px} H {viewport.right-10px} V {viewport.bottom-10px}, H {viewport.left+10px} z" stroke-width="{2px}"/>.

In some use cases, RCC can provide some of the low-level foundation features necessary to allow expression-based attribute values, but some form of expression evaluation engine, such as enhancing the SVG language to support the DOM3 XPath module, would be necessary. Assuming RCC and an expression evaluation facility, then potentially the above requirement could be solved by having the SVG content developer define a custom path definition element whose behavior had the ability to perform expression evaluation on the custom element attribute values and generate alternate SVG which represented the result of all of the expression evaluations. For example, the Original XML might look like <foo:ConstrainedPath d=" M {viewport.left+10px}, {viewport.top+10px} H {viewport.right-10px} V {viewport.bottom-10px}, H {viewport.left+10px} z" stroke-width="{2px}"/> and the Generated SVG would be a regular path element with numbers (the result of the expressions) replacing all of the bracketed terms in the Original XML. This approach has some parallelism with the CSS notion of specified vs computed values, where the expression language in the Original XML is like the CSS notion of a specified value and the flattened Generated SVG (after evaluation of the expression language) is like the CSS notion of a computed value.

An advantage which RCC plus an expression language would provide to implementers is that the low-level processing model for RCC-enabled SVG user agents would continue to be based on a simple user-unit model as in SVG 1.0/1.1, thereby allowing expression-based attribute value functionality without affecting the low-level user agent logic.

An example is not available in this draft.

3.2.8 Custom container elements and dynamic layout

Some applications require dynamic layout. RCC can sometimes help with dynamic layout by allowing the developer to define a custom container element which performs layout operations on its children. Dynamic layout algorithms might respond to screen size, zoom level, and the relationship of the content to each other (as determined by extracting information from semantically rich markup). For example, a styling transformation might leverage RCC to produce an organization chart from a purely hierarchical XML grammar, and the sizes and positions of the boxes could adapt to the length of the names of the various people. Another example is a dialog box layout manager which sets the position for (otherwise) standard SVG graphic objects and user interface objects.

A concrete example of dynamic layout is an online magazine which adjusts its layout based on the aspect ratio of the window. If the user's window is wide enough to show multiple articles in adjacent columns, then the online magazine might choose to show a multiple column rendering of the magazine. However, when the user's window becomes too skinny for multiple columns, the online magazine might switch to a single-column layout. The markup might look something like this:

<svg>
  ...

  <!-- XPointer reference to the location for the widgets extensions to SVG.
       The extensions convert the widget elements into low-level SVG. -->
  <extensionDefs xlink:href="rcc-dynlayout-01-exts.svg#dynlayout" />

  <foo:DynamicPageLayout>
    <foo:articles>
      <foo:article>
        <foo:title>Major war erupts</foo:title>
        <foo:para>War broke out around the world today...</foo:para>
      </foo:article>
      <foo:article>
        <foo:title>Two headed-chicken born</foo:title>
        <foo:para>The sleepy town of Frostbite Falls is excited about...</foo:para>
      </foo:article>
    </foo:articles>
  </foo:DynamicPageLayout>
  ...
</svg> 

With a wide window, the DynamicPageLayout custom element would generate appropriate shadow trees of SVG such that the war and the chicken articles displayed side-by-side. With a skinny window, the DynamicPageLayout custom element would stack the two articles vertically.

3.2.9 Authoring tool roundtripping

Right now, legacy authoring tools do an imperfect job of roundtripping their native data models via SVG. This is understandable because these authoring tools usually were designed before SVG was defined and thus support an overlapping but different feature set. It isn't surprising that there might be some data loss when writing then reading SVG.

However, if SVG were enhanced such that arbitrary XML could be transformed into an alternate dynamically generated (and dynamically updated) SVG version of the content, then authoring tools could export two things:

  1. The authoring tool's native data model expressed in XML using a private namespace
  2. A transformation from Original XML into Generated Alternative SVG

With this approach, the original authoring tool would recognize its own namespace and read the SVG files with no data loss. Other SVG processors might or might not recognize the private namespace. If not, then these SVG processors would at least be able to faithfully process the visual representation that results from the transformation into Generated Alternative SVG. In order to be able to read the Generated Alternate SVG from the shadow tree, of course, the importer would have to be RCC-enabled.

To facilitate interchange among SVG importers which cannot support RCC, it is recommended that SVG Generators offer users the ability to generate flattened, final-form SVG files, where all RCC-enabled custom elements have been replaced by at least one possible form of the Generated Alternative SVG, and the Generated Alternative SVG is included within the actual document structure.

An example is not available in this draft.

There is much discussion within the SVG Working Group about the validity of this use case. The primary goal is to develop a component model that useful for running, developing and authoring graphical content, not just a single environment. Public feedback on this general topic is invited.

3.2.10 Graphical UI for Semantic Web

The W3C has a vision for the Semantic Web where instead of millions of opaque, unknown web pages, mostly HTML and images, there instead is a network of metadata which describes both the content and relationships of all of the various resources that populate the web. A clear extension is that the content itself should be as semantically rich as possible rather than simply contain presentation-oriented HTML+images, presentation-oriented SVG, or other less semantically rich formats.

With RCC it would be feasible to create SVG-encoded, fully interactive Web content which retained all semantic richness. By constructing the SVG file so that it contains the original semantically rich XML tags and references an appropriate transformation from the original XML tags into SVG shadow trees that contain the final-form presentation.

An example is not available in this draft.

3.2.11 Extending SVG

XML was built to be extensible. While the SVG 1.0/1.1 specifications have some extensibility features, in practice few people attempt to extend SVG due to limitations in the extensibility capabilities. These limitations were well-known to the SVG 1.0 Working Group who decided to proceed with SVG 1.0 as defined and address extensibility more fully in a subsequent version. Confirming evidence that SVG 1.0/1.1 have extensibility limitations is available on SVG developer newsgroups, where several developers have encountered difficulty using the SVG 1.0 extensibility features.

The ability to render arbitrary XML in SVG might provide some major benefits in the whole area of extensibility and might allow many developers who wish to extend SVG the ability to do so easily and in a highly interoperable manner (i.e., once most implementations support SVG 1.2).

One example of extensibility would be as simple as a new text element which does exactly the same things as regular SVG text except that it adds the one extra feature of drawing a rectangle around the text. This might be useful for tooltips.

Another example of extensibility is vector effects. Leading graphical authoring tools offer the ability to apply vector effects to graphical objects. Typically, this consists of taking a simpler source graphic, such as a path, and then producing a more complex result graphic which might squiggle the path or apply multiple different fills and strokes to the path. Generally, authoring tools will produce SVG which only contains the complex result graphics, loses the original source path and loses the semantics about the vector effect that was applied.

This approach would allow the original path element to be inserted as is into the SVG document, and then the styling transformation would generate the result of the vector effect within the shadow tree.

An example is not available in this draft.

3.2.12 Z-order

One particular example of the use case for extending SVG that warrants special mention is the potential for using custom elements to provide some ability to change the drawing order of elements. It might use the ability to define custom elements to create a new grouping element such as foo:ReorderableGroup. The elements within foo:ReorderableGroup might have a custom attribute which provides a z-index value. The transformation might reorder these elements within the Alternate SVG to achieve drawing order which is different than the logical order within the Original XML.

An example is not available in this draft.

3.3 Design requirements

The following is a very preliminary list of design requirements for the rendering arbitrary XML feature set. It is expected that this list will be adjusted significantly in subsequent versions of the SVG 1.2 specification. In the list below, must means that the item is an absolute requirement; should means that there may exist valid reasons in particular circumstances to ignore the item, but the full implications must be understood and carefully weighed before choosing a different course; may means that item will be considered, but further examination is needed to determine if the item should be treated as a requirement. The must, should and may designations are very preliminary and are thus very much subject to change in future versions. This preliminary version is being published as is to allow for early public feedback.

  1. must allow for the transformation of arbitrary Original XML into alternative SVG which provides final-form, low-level graphical presentation and behavior.
  2. must allow for re-usable widgets and/or components to be developed by third parties and posted at Web locations for use by reference by the SVG content developer community.
  3. must be as elegant a solution as possible, where elegance is achieved when there is lots of power yet keeping things simple. One indicator of elegance is the ratio of enhanced language power divided by the complexity of the new features. (Enhanced language power might be measured by the number of use cases that benefit from the new features. Complexity might be measured by the amount of additional text in the SVG specification or the implementation time required to add the new features to an existing SVG 1.0 implementation or the number of new elements, attributes and properties added because of the new feature.)
  4. must be recursive. That is, RCC can be applied to the result of RCC.
  5. must be compatible with progressive rendering (i.e., you don't need to have the entire document downloaded before transformations from Original XML into Generated SVG can begin)
  6. should provide a foundation for developing a combined SVG+XForms processor.
  7. should be compatible with XML Events; in particular, allow for custom events on the custom elements within the Original XML.
  8. should allow for ways for bi-directional linking of original XML data into generated SVG presentation/behavior.
  9. must allow any symbols, components or template elements to be referenced from an external file.
  10. may allow for custom objects that do not actually get rendered for requirements such as adding drag-and-drop to an element and in-place editing. Thus, not only mapping of a model element to a widget shadow tree but also an attribute triggering DOM calls on the existing tree.
  11. must allow for creating custom, slightly-extended versions of existing SVG elements. One example is the ability to create an element called foo:Layer which is nearly identical to a g, which maps to a g within the Generated SVG Tree and whose content model matches exactly that of a g. This custom grouping element might or might not have custom attributes in a private namespace; even if entirely identical to a g the simple renaming of the element might help certain workflows recognize that this particular type of group has special meaning (a potential accessibility benefit) or gets special treatment in particular workflows. Another example might be a custom element foo:MyPath which is a slight modification on a path element, perhaps allowing multiple strokes (versus the restriction of a single stroke on SVG's existing path element).
  12. should be theoretically possible to write a transformation in script which transforms either CSS-styled arbitrary XML or MathML into final-form SVG. These two scenarios are litmus tests to verify the robustness of the approach.
  13. should be compatible with XML Schema for validation purposes on the SVG with Original XML
  14. should avoid messy scripting problems, such as the real DOM changing in unexpected ways as a result of the Original XML to Alternate SVG transformation, which would make script development difficult. For example, the application of the transformation should not cause standard firstChild and nextSibling DOM operations to produce different results.
  15. should not have adverse effects on DOM serializations (DOM load/save) due to the application of the transformation. Thus, if the Original XML has not been modified by DOM operations such as scripting, then DOM serialization should save out the original content, not the resulting Alternate SVG.
  16. must take into account accessibility concerns.
  17. must take into account internationalization concerns.
  18. should be able to animate any aspect of the Original XML content and have the animated reflected in real-time in the Generated Alternative SVG.

3.4 Element definitions

3.4.1 The extensionDefs element

The extensionDefs element registers a set of custom elements, all of which are in the same namespace.

The extensionsDefs element can be used in either of two ways. First, the custom elements can be defined within the content of the extensionDefs element, most significantly via elementDef child elements. Here is an example which defines two custom elements, equilateral-triangle and rhombus, in the "http://example.org" namespace:

<extensionDefs namespace="http://example.org">
  <elementDef name="equilateral-triangle">...</elementDef>
  <elementDef name="rhombus">...</elementDef>
</extensionDefs>

Alternatively, the extensionDefs element can include an xlink:href attribute (i.e., an href attribute in the XLink namespace) which specifies an XPointer value to a different extensionDefs element, most often located in a different file or resource.

Here is a snippet from the SVG file which will get displayed:

<extensionDefs xlink:href="http://example.org/cool/cool.svg#CoolExtensions"/>
<g xmlns:cool="http://example.org/cool">
  <cool:bellbottoms x="20" y="60" width="40" height="200"/>
  <cool:leisuresuit x="80" y="60" width="40" height="200"/>
</g> 

Here is a snippet from the referenced SVG file which defines the extensions:

<extensionDefs id="CoolExtensions" namespace="http://example.org/cool">
  <elementDef name="bellbottoms">...</elementDef>
  <elementDef name="leisuresuit">...</elementDef>
</extensionDefs> 

The following is a schema snippet which defines the extensionDefs element:

<xs:element name='extensionDefs'>
  <xs:complexType>
    <xs:choice minOccurs='0' maxOccurs='unbounded'>
      <xs:element ref='elementDef'/>
      <xs:element ref='defs'/>
      <xs:element ref='script'/>
    </xs:choice>
    <xs:attributeGroup ref='PresentationAttrs'/>
    <xs:attributeGroup ref='StyleAttrs'/>
    <xs:attribute ref='xlink:href'/>
    <xs:attribute name='namespace' type='anyURI'/>
  </xs:complexType>
</xs:element> 

The above schema may need to be modified to constrain the grammar such that there can be either an xlink:href attribute which points to the real definition of the extensions (probably in a separate file) or a combination of namespace attribute and content, which would be required if xlink:href is not present.

Attributes:

xlink:href:
XPointer to another extension, possibly in a different file. If an xlink:href is specified, then it must reference a different extensionDefs element and that extensionDefs element itself must not have an xlink:href attribute; otherwise, the element is in error. If an xlink:href is specified, then certain other attributes (e.g., namespace) and child elements (e.g., elementDef element must not be present; otherwise, the element is in error. (Note: include hyperlink to Error Handling appendix).
namespace:
Namespace URI for the elements defined in the extension. If the namespace attribute is present, the extensionDefs must not have an xlink:href attribute.

There is an open issue about whether it should be possible to define custom elements within the SVG namespace and whether any elements in the SVG namespace should have shadow trees. The current feeling is that custom elements must be outside the SVG namespace (http://www.w3.org/2000/svg) and the XML namespace (http://www.w3.org/XML/1998/namespace). See Open Issues below.

3.4.2 The elementDef element

The elementDef element is used to define a custom element. It encapsulates all information about the element. Also, all event listeners for this element are implicitly attached to the custom elements that it defines. That makes it convenient to put script elements with XMLEvent ev:type attribute as its children or use event attributes (e.g., onactivate or onmousemove).

The most essential function of the elementDef element is to control the definition of the shadow tree for the given custom element. The shadow tree is built from some combination of automatic cloning of the contents of the prototype child element and DOM manipulation of the shadow tree via DOM manipulation such as scripting.

The shadow tree can include instances of other custom elements, in which case elementDef processing happens recursively.

The following is a schema snippet which defines the elementDef element:

<xs:element name="elementDef">
  <xs:complexType> 
    <xs:choice  minOccurs="0" maxOccurs="unbounded">
      <!-- xsd:group ref="svg:desc-title-metadata"/>
      <xs:element ref="defs"/>
      <xs:element ref="prototype"/>
      <xs:element ref="script"/>
    </xs:choice>
    <xs:attributeGroup ref="PresentationAttrs"/>
    <xs:attributeGroup ref="StyleAttrs"/>
    <xs:attribute name="name" type="NCName" use="required" /> 
    <!-- anything else??? --> 
  </xs:complexType>
</xs:element> 

The above schema may need to be modified to constrain the grammar so that only one prototype element can be specified.

The name attribute specifies the name of the element being defined.

3.4.3 The defs element

This is the standard SVG defs element. Its purpose as a child of elementDef is to be a container for the various resource elements that might be referenced by other elements within the elementDef. The defs is most commonly used to define referenced objects such gradients, filters or symbols, but there are no restrictions for the contents with the defs.

3.4.4 The prototype element

This element is used to define an initial shadow tree for the custom element defined by its parent. The contents of the prototype element are copied onto the 'shadowTree' DOM property for the custom element.

The prototype element is optional. If not present, there is no automatic cloning into the shadow tree. However, even without a prototype element, the shadow tree can still contain contents due to the possibility of DOM manipulation via other means such as scripting.

Because shadow trees can contain instances of other custom elements, it is allowed that a prototype element contains other custom elements.

3.4.5 The refContent element

The refContent element is often an essential feature when the content developer requires a custom container element. One example of a custom container element is a custom scrollArea element where the contents should render normally except with customized translations and clipping due the special container element behavior.

With refContent, the contents of the container do not get cloned into the shadow DOM; instead, the shadow DOM refers back into the custom element's DOM (the original DOM) for some of the graphics to be rendered. In addition to allowing an effective subclassing of SVG's container elements such as g, refContent offers potential performance and memory-saving benefits by preventing duplication of the DOM when such duplication is unnecessary or undesirable.

The refContent element acts as a virtual grouping element within the shadow DOM for a set of referenced elements in the custom element's DOM. The effect in terms of rendering and behavior is as if the referenced elements had been moved into the shadow DOM temporarily in order to accomplish the necessary rendering operations and behaviors (e.g., hit testing).

Using the optional select attribute, refContent can specified a subset of the custom element's descendants.

It is legal to have multiple refContent elements in the shadow subtree, but the subsets of the children that they select must not intersect.

In the example below, a ui:scrollArea custom element establishes a scrollable region onto which any SVG content can be rendered:


<extensionDefs...>
  <elementDef name="scrollArea">
    <prototype>
      <svg ...>
        <refContent/>
      </svg>
      <!-- assume a scrollbar custom element is defined elsewhere -->
      <ui:scrollbar.../>
    </prototype>
    <!-- etc. -->
  </elementDef>
</extensionDefs>

<ui:scrollArea>
  <image .../>
  <path ... />
  <text...>...</...>
  <!-- etc. -->
</ui:scrollArea> 

In the simple flowchart example provided earlier, the flowchart custom element itself is a container for other flowcharting custom elements such as processNode and terminalNode. The implementation of the flowchart custom element takes advantage of refContent to simply refer to the custom element's (i.e., the flowchart element's) original content (i.e., a list of processNode and terminalNode custom elements):

<extensionDefs...>
  <elementDef name="flowchart">
      <prototype><refContent/></prototype>
      <!-- etc. -->
  </elementDef>
</extensionDefs>

<flowchart xmlns="http://example.org/rcc-flowcharts"...>
  <terminalNode>Start</terminalNode>
  <processNode>Step 1</processNode>
  <processNode>Step 2</processNode>
  <terminalNode>End</terminalNode>
</flowchart> 

The refContent element is defined as follows:

<xs:element name="refContent">
  <xs:complexType>
    <xs:sequence>
      <!-- xsd:group ref="svg:desc-title-metadata" minOccurs="0" maxOccurs="unbounded"/>
      <xs:attributeGroup ref="PresentationAttrs"/>
      <xs:attributeGroup ref="StyleAttrs"/>
      <xs:attribute name="select" type="???" use="optional" /> 
      <xs:attribute name="transform" type="???" use="optional" /> 
      <!-- event attributes??? overflow/clip??? -->
      <!-- anything else??? -->
    </xs:sequence>
  </xs:complexType>
</xs:element> 

The select attribute defines an XPath selector for the node set that should be connected here. Only a small subset of XPath is allowed: "*", "name", "*[#]", "name[#]" where name is any identifier and # is a number

3.4.6 The script element

This is the standard SVG script element, except that it also contains additional attributes ev:event) to allow it to register itself as an event listener on the custom elements.

3.5 RCC support in the SVG DOM

On the DOM level, all custom elements have a shadowTree attribute that points to an SVGShadowElement.

If this attribute is null (which it normally is), then an element "behaves normally". For example, normal behavior for foreign namespace elements is that they don't get rendered. However, if this attribute is not null, all rendering and interactive behavior is determined by the content of this attribute. This affects all behavioral aspects of the element (rendering, hit testing, layout, UI events etc.), but not its "DOM" aspects (Core DOM calls, document events, mutation events, etc.)

The node which is attached to an element through an 'shadowTree' DOM property is said to belong to the "Shadow DOM". It remains a normal Node in all respects, though. A Node can be attached only to one element at a time and it must not have a parentNode. From the Core DOM point of view, it is not attached to the document tree (which is perfectly legal). It is legal for a Node owned by one document to be attached to the element from another document as well. And it is also legal for the "Shadow DOM" Nodes to have their own "shadow" subtrees attached (through their nested own 'shadowTree' DOM properties).

SVG DOM should provide a method to set the 'shadowTree' of an element. With such a method, RCC DOM can be used even without an associated syntax. Also there should be a method to obtain an element given its shadow DOM root. Here is an initial proposal, which introduces new interfaces SVGShadowElement and SVGShadowable:

interface SVGShadowElement : Element { 

   Element getShadowOwnerElement() raises ... ;

}

interface SVGShadowable {

  readonly attribute SVGShadow Element shadowTree ;

  void setShadowTree (in SVGShadow Element newShadow) raises ...; 
} 

All unknown elements (generally, all elements in a different namespace) implement interface SVGShadowable.

3.6 RCC Events

Two new events are defined to support the RCC feature set: SVGBindBegin and SVGBindEnd. SVGBindBegin is fired when the user agent encounters a new custom element and has added the element to the DOM tree. SVGBindBegin must be fired before the element's descendants have been added to the tree and therefore before any of the descendants' SVGBindBegin and SVGBindEnd events have been fired. SVGBindEnd is fired when the user agent has finished adding the element's children to the tree and has fired all SVGBindBegin and SVGBindEnd events that might apply to descendants. The two new event types extend dom::Event. The event target is the custom element.

For progressive rendering, any content between the custom element's start tag and end tag fires mutation events. If it is necessary to listen to and handle these mutation events, developers generally will attach mutation event listeners as part of the SVGBindBegin event handler.

This section needs more description on setting up events to manage mutation events on the custom element.

3.7 Implementation Notes

In order to ensure interoperability:

Any script elements inside of extensionDefs elements which do not have an ev:event attribute get evaluated once at the time the script elements contents have been added to the DOM tree. (The result of evaluation often adds function definitions to the scripting environment, and these function are available indefinitely.) On the other hand, script elements inside of extensionDefs elements which do have an ev:event attribute get evaluated every time the given event occurs, similar to how event attributes such as onclick get re-evaluated every time the user clicks on the given element.

Circular references within the definitions of custom elements must raise an error. The shadow tree for a custom element must not contain the same custom element directly or indirectly. An example of illegal indirection would be where custom element A includes an instance of custom element B, which is OK, but then custom element B in turn includes an instance of custom element A, which is an indirect circular reference and must raise an error.

3.8 Open Issues

Here are some of the open issues that have been raised regarding potential RCC features that allow for transformation of semantically rich arbitrary XML into presentation-rich alternative SVG.

  1. Where does the Alternative Generated SVG go? Does the generated SVG become part of the real DOM (which means the generated SVG could be reached via firstChild, nextSibling, etc. off of the main document tree) or does the generated SVG go into some sort of shadow DOM (which means the generated nodes can be reached, but not via firstChild, nextSibling, etc. on the main document tree). Some of the arguments in favor of shadow trees are:

    Some of the arguments against shadow trees:

    Resolution: alternate generated SVG goes onto a shadow tree in the form of a DOM attribute off of the custom element.

  2. What events trigger a recalculation operation from Original XML into Alternate SVG? One candidate is that by default regeneration is triggered by DOM Mutation events.

    Resolution: regeneration of shadow tree is triggered via event handling/listener which is manually established using XML event listeners.

  3. How does XML Events relate to this feature?

    Resolution: the feature will use XML events for event handling.

  4. Is the primary use case "skinning" XForms, more general UI widgets, or defining a way of presenting (SVG) views of arbitrary XML data? (This issue is discussed in more detailed under Possible Approaches above.)

    Resolution: the current approach seems to cover most situations in both cases.

  5. Is a kind of use that leverages XForm's instance model, or is it a new templating language?

    Resolution: the working group is still working on the relationship of the arbitrary XML features in RCC with the arbitrary XML features in XForms. There is an example earlier which shows how XForms might work with RCC. Certainly, there are templating aspects to RCC, but it more like an extensibility mechanism that maps XML namespaces into presentation+behavior than just a templating facility.

  6. Should the mapping be one way or two way (ie. should there be a way to automatically reflect changes in the transformed content when the transformation is updated?)

    The working group is still working on this aspect of the feature.

  7. Bidirectionality, particularly event mapping, almost certainly will require custom scripting in some circumstances. How far should RCC go in trying to minimize the number of situations where scripting is required?

    The working group is still working on this aspect of the feature. We'll know more after users try out the feature and send in their reports.

  8. Dependency mapping (i.e., which fragments of Original XML relate to which fragments of Generated SVG) is highly desirable but also will likely require custom scripting in some circumstances. How much leverage might RCC get from adopting XForms' approach to instance data? How feasible is it for implementations to do automatic dependency mapping? How far should RCC go in trying to define markup which explicitly defines dependencies?

    The working group is still working on this aspect of the feature.

  9. Should the feature be enabled by the styling system (ie. should you be able to apply a style rule that converts all myns:pie elements into a combination of svg:path elements?)

    The working group is still working on this aspect of the feature.

  10. Is this an extension to the use element?

    Resolution: no, we aren't just going to add new options to the use element.

  11. If a declarative syntax is used, SVG implementations may be required to support XPath and some simple XSLT features. Will the XSLT features be too much of an implementation burden?

    The working group is still working on this aspect of the feature.

  12. What features are available in SVG Full vs SVG Basic vs SVG Tiny?

    Current thinking in the working group is that RCC is required in both Full and Basic. The working group is studying approaches where a subset of features could be made available in Tiny. The big problem with SVG 1.1 Tiny is that scripting is not part of Tiny, and the current design generally requires scripting support.

  13. We might want a different name instead of "RCC", particularly because the feature goes beyond rendering.
  14. Each document referenced through extensionDefs has its own script context?
  15. Will it be possible to animate the attributes and properties within custom elements? There has been considerable discussion within the working group about extending RCC to allow for custom attributes and/or custom behaviors in addition to custom elements. One of the challenges with custom attributes is that XML defines the list of attributes on an element to be unordered. Also, there is no natural place to put a shadow tree onto an attribute. The working group is considering several different approaches, each of which has some positives and negatives. It is likely that a subsequent public draft will provide more clarity on this issue.
  16. Do we want to define a shadowTree element? This could hold the flattened result of the recursive shadow tree on a custom element and would be useful in printing workflows, which may not have a scripting engine.
  17. If RCC extension comes from a separate document, are shadow tree elements still owned by that document?

    Suggested resolution: no, shadow tree elements are owned by document with the custom element, not the document with the custom element's elementDefs

  18. Subclassing elementDef - should there be mechanisms to facilitate subclassing of extensionDefs, where you use most of a different elementDef's look and behavior but override just one aspect?

    Suggested resolution: no.

  19. Should elements in the SVG namespace be allowed to have shadow trees? Clearly, it is undesirable for certain elements (e.g., extensionDefs, elementDef, prototype) to have shadow trees due to implementation recursion problems, so not all SVG elements could have shadow trees. A major consideration is forward and backwards compatibility and what happens across different versions and profiles. Another consideration is the following language from the F.2 Error Processing section of the SVG 1.1 specification: "...an SVG document fragment is technically in error... when an element or attribute is encountered in the document which is not part of the SVG DTD and which is not properly identified as being part of another namespace... when an element has an attribute or property value which is not permissible according to this specification" . The current feeling within the SVG working group is that it is too hard to allow shadow trees on elements in the SVG namespace, but we are interested in hearing public comment on the desirability of this. If SVG elements can also have shadow trees (i.e., not just non-SVG elements), which gets rendered first - the SVG element or the shadow tree, or maybe should we have an attribute to control this?
  20. We need to disallow all types of circular referencing. For example, prototype elements cannot reference the custom element which is being defined, itself, or anything within its content.
  21. Do we want to disallow the SVG namespace URI within the 'namespace' attribute on extensionDefs?
  22. Do we want to add an expression evaluation facility such as DOM3 XPath to the SVG DOM as a complementary feature to RCC to enable RCC to be used in application areas which require expression-based attribute values?

3.9 Live Templates: an alternate approach to RCC

Live Templates is the name of an alternate proposal to the Rendering Custom Content feature. The Live Templates proposal has not received as much examination and discussion from the SVG Working Group as the RCC proposal. It is included here for public feedback.

The SVG Working Group believe that it can reconcile the RCC and LiveTemplates proposals, taking the best features from each to produce a better final proposal.

The objective of Live Templates is to improve SVG's usability as a front-end for fully interactive Web applications. In classical UI, the data model is in any appropriate XML grammar, the view is SVG, and there is the ability to view (transform the XML to SVG), edit (manipulate the view via DOM or post instructions to a server that would change the XML), and update the view (incrementally change only those parts of the SVG that are affected by changes in the XML, thereby avoiding a complete screen refresh).

There are three main uses of Live Templates:

  1. Viewing and editing of an "application data model" stored as XML on the server - for example the current state of any collaborative application's data, which must be stored centrally for all to access and edit.
  2. Templating of sub-trees of SVG (i.e. a more general 'use'), which is achieved by allowing generateContent to refer to a subtree of the current document as input.
  3. Storing and re-styling current user state information rather than requiring unnecessary visits back to the server (i.e. a "user data model" as separate from the "application data model"). This is achieved by using the current state of the DOM for input rather than the original document.

Refer also to the design objectives and requirements of the RCC, they apply to Live Templates as well.

3.9.1 Overview

Live Templates provides the ability to run a specified XML transformer on a specified XML file or branch of the DOM with specified parameter values, and place the results as a generated SVG sub-tree in a specified location in the SVG. An XML transformer is something that takes XML as input, and produces XML as output, like an XSLT stylesheet.

The newly generated SVG subtree could be placed either directly in the DOM or as a shadow tree accessible as a separate DOM tree by calling a method on the element that generates this shadow tree .

Live Templates also provides ability to re-run the XSLT/XML transformer at any time to replace just the generated results, while leaving the rest of the SVG untouched.

This idea of running a script or other process on an input file to produce a generated SVG sub-tree is not specific to XSLT, or to XML input, so it should be possible, in theory, to specify the MIME type of the script file to be something else like XQuery, Java, or ECMAScript. Let's make XSLT the default and a priority for implementers.

3.9.2 The generateContent element

The generateContent element allows an XML transformer such as an XSLT stylesheet to be run on a specified template XML file or fragment and the results inserted as a shadow tree of the generateContent element. The shadow tree is accessible via a DOM call on the generateContent element.

The generateContent, like the use element, has optional attributes x, y, width and height which are used to map the generated graphical contents onto a rectangular region within the current coordinate system.

Should the 'generateContent' to have similar viewport establishing attributes and behavior as the 'use' element or the 'svg' element?

A DOM method is provided so that script writers may regenerate the shadow tree from template XML at any time. The shadow tree is only generated at two possible times:

  1. When the document is initially rendered.
  2. When the DOM method to regenerate the tree is called.

A generateContent element has the same visual effect as if the generateContent element was replaced by the shadow tree it generates.

General discussion of shadow tree inheritance, DOM access, and event model should be referenced from here.

We may want to fire an event before the shadow tree is generated and afterwords for script writers. An argument can be made against this, as it encourages doing a lot of rendering "fix-up" in a non-declarative manner with ECMAScript.

Example Use01 below has a simple 'generateContent' referencing an external template for a simple shape and an XML transformer that creates the SVG for the shape.

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

     <generateContent 
         x="10" y="10" width="30" height="30"
         transformer="shapes.xsl"
         type="text/xsl" 
         input="diamondInstance.xml" />

</svg> 

The referenced template file:

diamond  xmlns="http://foo.example.org/shapes" /> 

The referenced XML transformer file:

<xsl:stylesheet version="1.1" 
 xmlns="http://www.w3.org/2000/svg"
 xmlns:foo="http://foo.example.org/shapes"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="foo:diamond">
  
  <rect transform="rotate(44,50%,50%)"
   fill="red"
   width="100%" 
   height="100%"/>

 </xsl:template>

</xsl:stylesheet> 

The visual effect would be equivalent to the following document:

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

     <g transform="translate(10,10)"> 
         <svg width="30" height="30" >

          <rect transform="rotate(44,50%,50%)"
           fill="red"
           width="100%" 
           height="100%"/>

         </svg >
     </g >

</svg> 

Example Use02 below has a generateContent referencing an external template for a simple button and an XML transformer that creates the SVG for the button.

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<style type="text/css"<>![CDATA[
      .pushButton {
        fill: green;
        stroke: black;
        stroke-width: 3
      }
    ]]<>/style>

<script type="text/ecmascript"< <![CDATA[

  var angle = 0;

  function myCallback(evt) {

    var document = evt.target.ownerDocument;
    var elem = document.getElementById( "message" )

    // set rotation transform attribute on text.
    angle = angle + 10;
    var transform = "rotate(" + angle + " 100,20 )";
    elem.setAttribute( "transform", transform );
  }

  ]]> </script>


<text id="message" x="20" y="20" font-size="10">Below is a button, please press it</text>

     <generateContent 
         x="10" y="10" width="30" height="30"
         transformer="buttons.xsl"
         type="text/xsl" 
         input="buttonInstance.xml" />

</svg> 

The referenced template file:

<pushButton xmlns="http://bar.example.org/buttons" action="myCallback(evt)"/> 

The referenced XML transformer file:

<xsl:stylesheet version="1.1" 
        xmlns="http://www.w3.org/2000/svg"
        xmlns:bar="http://bar.example.org/buttons"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <xsl:template match="bar:pushButton">
                
                <xsl:variable name="action" select="./@action"/>

                <g class="pushButton" fill="blue" onclick="{$action}" >

                <rect width="100%" height="100%"/>
                        <svg x="10%" y="10%" width="80%" height="80%">

                                <xsl:apply-templates select="./*"/>

                        </svg>

                </g>
        </xsl:template>
</xsl:stylesheet> 

The effect would be equivalent to the following document:

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<style type="text/css"<>![CDATA[
      .pushButton {
        fill: green;
        stroke: black;
        stroke-width: 3
      }
    ]]<>/style>

<script type="text/ecmascript"< <![CDATA[

  var angle = 0;

  function myCallback(evt) {

    var document = evt.target.ownerDocument;
    var elem = document.getElementById( "message" )

    // set rotation transform attribute on text.
    angle = angle + 10;
    var transform = "rotate(" + angle + " 100,20 )";
    elem.setAttribute( "transform", transform );
  }

  ]]> </script>

<text id="message" x="20" y="20" font-size="10">Below is a button, please press it</text>

     <g transform="translate(10,10)"> 
         <svg width="30" height="30" >

                <g class="pushButton" fill="blue" onclick="myCallback(evt)" >

                <rect width="100%" height="100%"/>
                        <svg x="10%" y="10%" width="80%" height="80%"/>

                </g>

         </svg >
     </g >

</svg> 

Example Use03 below has a generateContent combining the two above examples to put the diamond on the button as a label.

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<style type="text/css"<>![CDATA[
      .pushButton {
        fill: green;
        stroke: black;
        stroke-width: 3
      }
    ]]<>/style>

<script type="text/ecmascript"< <![CDATA[

  var angle = 0;

  function myCallback(evt) {

    var document = evt.target.ownerDocument;
    var elem = document.getElementById( "message" )

    // set rotation transform attribute on text.
    angle = angle + 10;
    var transform = "rotate(" + angle + " 100,20 )";
    elem.setAttribute( "transform", transform );
  }

  ]]> </script>

<text id="message" x="20" y="20" font-size="10">Below is a button, please press it</text>

     <generateContent 
         x="10" y="10" width="30" height="30"
         transformer="shapesAndButtons.xsl"
         type="text/xsl" 
         input="diamondButtonInstance.xml" />

</svg> 

The referenced template file:

<bar:pushButton xmlns:bar="http://bar.example.org/buttons" 
                action="myCallback(evt)">
        <foo:diamond xmlns:foo="http://foo.example.org/shapes" />
</bar:pushButton> 

The referenced XML transformer file:

<xsl:stylesheet version="1.1" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <xsl:import href="buttons.xsl"/>
        <xsl:import href="shapes.xsl"/>

</xsl:stylesheet> 

The effect would be equivalent to the following document:

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<style type="text/css"<>![CDATA[
      .pushButton {
        fill: green;
        stroke: black;
        stroke-width: 3
      }
    ]]<>/style>

<script type="text/ecmascript"< <![CDATA[

  var angle = 0;

  function myCallback(evt) {

    var document = evt.target.ownerDocument;
    var elem = document.getElementById( "message" )

    // set rotation transform attribute on text.
    angle = angle + 10;
    var transform = "rotate(" + angle + " 100,20 )";
    elem.setAttribute( "transform", transform );
  }

  ]]> </script>

<text id="message" x="20" y="20" font-size="10">Below is a button, please press it</text>

     <g transform="translate(10,10)"> 
         <svg width="30" height="30" >

                <g class="pushButton" fill="blue" onclick="myCallback(evt)" >

                <rect width="100%" height="100%"/>
                        <svg x="10%" y="10%" width="80%" height="80%">
                            <rect transform="rotate(44,50%,50%)"
                             fill="red"
                             width="100%" 
                             height="100%"/>

                        </svg >
                </g>

         </svg >
     </g >
</svg> 

Example Use04 below has a generateContent transformer and input xml in the same file.

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<script id="diamond" type="text/xsl"< 
  <xsl:stylesheet version="1.1" 
   xmlns="http://www.w3.org/2000/svg"
   xmlns:foo="http://foo.example.org/shapes"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  
   <xsl:template match="foo:diamond">
    
    <rect transform="rotate(44,50%,50%)"
     fill="red"
     width="100%" 
     height="100%"/>
  
   </xsl:template>

  </xsl:stylesheet>
</script>

     <generateContent 
         x="10" y="10" width="30" height="30"
         transformer="#diamond"
         type="text/xsl" 
         input="#diamondInstance" />

<metadata>
  <diamond id="diamondInstance" xmlns="http://foo.example.org/shapes" />
</metadata>

</svg> 

Example Use05 below has a generateContent referencing an XML transformer that allows binding SVG events to generated content.

The referenced template file:

<foo:teleportCircle  
        xmlns="http://www.w3.org/2000/svg"
        xmlns:foo="http://foo.example.org/teleport"
        
        foo:url="http://www.w3c.org"
        cx="100" cy="100" r="30" fill="red" onmouseover="myCallback(evt)">
</foo:teleportCircle> 

The referenced XML transformer file:

<xsl:stylesheet version="1.1" 
        xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        xmlns:foo="http://foo.example.org/teleport"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <xsl:template match="foo:teleportCircle">
                
                <xsl:variable name="url" select="./@foo:url"/>

                <a xlink:href="{$url}">
                        <circle>
                                <xsl:for-each select="./@*[name() != 'onclick' and name() != 'foo:url']">
                                        <xsl:variable name="attrName" select="name()"/>
                                        <xsl:attribute name="{$attrName}"><xsl:value-of select="."/></xsl:attribute>
                                </xsl:for-each>
                        </circle>
                </a>

        </xsl:template>

</xsl:stylesheet> 

The effect would be equivalent to the following document:

<svg width="10cm" height="3cm" viewBox="0 0 100 30" version="1.2"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<style type="text/css"><![CDATA[
      .pushButton {
        fill: green;
        stroke: black;
        stroke-width: 3
      }
    ]]></style>

<script type="text/ecmascript"> <![CDATA[

  var angle = 0;

  function myCallback(evt) {

    var document = evt.target.ownerDocument;
    var elem = document.getElementById( "message" )

    // set rotation transform attribute on text.
    angle = angle + 10;
    var transform = "rotate(" + angle + " 100,20 )";
    elem.setAttribute( "transform", transform );
  }

  ]]> </script>

<text id="message" x="20" y="20" font-size="10">Below is a teleporter</text>

<a xlink:href="http://www.w3c.org">
        <circle cx="100" cy="100" r="30" fill="red" onmouseover="myCallback(evt)"/>
</a>

</svg> 

TODO: a DTD or schema fragment.

Attribute definitions:

x = " <coordinate>"
The x-axis coordinate of one corner of the rectangular region into which the shadow tree placed. If the attribute is not specified, the effect is as if a value of "0" were specified. Animatable : yes.
y = " <coordinate>"
The y-axis coordinate of one corner of the rectangular region into which the shadow tree is placed. If the attribute is not specified, the effect is as if a value of "0" were specified. Animatable : yes.