Copyright © 2004 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
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.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document is the sixth public working draft of the SVG 1.2 specification. It lists the areas of new work in version 1.2 of SVG and is not a complete language description. The SVG Working Group consider the feature set of SVG 1.2 to be approaching stability. However, there are some cases where the descriptions in this document are incomplete and simply show the current thoughts of the SVG Working Group on the feature, or list the open issues. Therefore, this document should not be considered stable.
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 as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
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 creation of SVG Viewers which correspond to profiles other than Tiny, Basic, or Full is discouraged; experience in SVG and other formats shows that proliferation of viewers with subtly differing capabilities is a hindrance to interoperability.
Sometimes, vertically-focused industries can improve interoperability by defining and clearly documenting an industry-specific profile which uses an existing baseProfile as a starting point.
On the other hand, creation of particular profiles for different types of content authoring is encouraged, provided the baseProfile is set appropriately to the closest standard profile which is a true superset of the authoring profile. Use of such documented profiles can aid interchange of graphical assets between authoring tools.
As an example, a profile aimed at technical illustration might be based on SVG Basic, omit filter effects, and retain animation and scripting to allow for interactive diagrams. A profile for interchange of graphics arts assets might be based on Full, retain filter effects, and omit animation, scripting, and foreignObject - thus ensuring that graphics conforming to that profile can be easily edited in a variety of graphical editors.
A future version of the SVG specification might include instructions for defining industry-specific profiles.
SVG 1.2 enables a block of text and graphics to be rendered inside a shape, while automatically wrapping the objects into lines, using the flowRoot element. The idea is to mirror, as far as practical, the existing SVG text elements.
The flowRoot element specifies a block of graphics and text to be rendered with line wrapping. It contains at least one flowRegion element, defining regions into which the children elements of the flowRoot should be flowed.
The following is an extract of an XML Schema that describes the flowRoot element.
<xs:element name="flowRoot">
<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>
In order to reduce the burden on Tiny implementations, the Working Group is considering allowing flowPara as a child of flowRoot. This would mean that the Tiny module could require only a single flowPara.
The flowRegion element contains a set of shapes and exclusion regions in which the text content of a parent flowRoot 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 flowRoot 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 flowRoot 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 an 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:element ref="use" minOccurs="0" maxOccurs="unbounded"/>
<xs:group ref="flowRegionExclude" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs: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 flowRoot then it describes exclusion regions for all flowRegion children of the flowRoot.
The following is an 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:element ref="use" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
The flowDiv element specifies a block of text and/or graphics to be inserted into the layout, and marks it as a division of related elements. 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 an 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>
The flowPara element marks a block of text and graphics as a logical paragraph.
The following is an 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:element ref="flowImage"/>
</xs:choice>
<xs:attributeGroup ref="PresentationAttrs"/>
<xs:attributeGroup ref="StyleAttrs"/>
</xs:complexType>
</xs: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 an 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="flowImage"/>
<xs:element ref="flowRegionBreak"/>
</xs:choice>
<xs:attributeGroup ref="PresentationAttrs"/>
<xs:attributeGroup ref="StyleAttrs"/>
</xs:complexType>
</xs: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 an extract of an XML Schema that describes the flowRegionBreak element.
<xs:element name="flowRegionBreak"> <xs:complexType/> </xs: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 an 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="flowImage"/>
<xs:element ref="flowRegionBreak"/>
</xs:choice>
<xs:attributeGroup ref="PresentationAttrs"/>
<xs:attributeGroup ref="StyleAttrs"/>
</xs:complexType>
</xs: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 an 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>
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 an 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>
The flowImage element defines a container for graphics which are to be rendered inline in the text layout. It can be used to insert images or any other graphic object that will then flow inline with the text flows.
The flowImage element establishes a new viewport for contained graphic elements. If flowImage specifies an absolute size, that size is used as the bounding rectangle for the flowImage region. If flowImage specifies a percentage as its size, the percentage is represented as a percentage of the current viewport.
In the absence of either width or height on the flowImage element, no new viewport is established. Any contained graphic elements are sized relative to the current viewport. In that case, the bounds of the flowImage element are calculated from the bounding box of any contained child graphic elements.
The following is an extract of an XML Schema that describes the flowImage element.
<xs:element name="flowImage">
<xs:complexType mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="image"/>
<xs:group ref="ShapeElements"/>
<xs:element ref="g"/>
</xs:choice>
<xs:attribute name="width" type="CoordinateType" use="optional"/>
<xs:attribute name="height" type="CoordinateType" use="optional"/>
</xs:complexType>
</xs:element>
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:
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.
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.
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.
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.
Flowing text using system fonts is a difficult operation. Content developers should not expect reproducible results between implementations. The most likely scenario for a reproducible result, although still not completely guaranteed, will be achieved by using SVG Fonts.
Horizontal alignment in flowing text is provided by the text-align property. It is a modified version of the CSS3 property.
| Value: | start | end | before | after | center | justify |
| Initial: | start |
| Applies to: | flowText, flowPara, flowDiv elements |
| Inherited: | yes |
| Percentages: | N/A |
| Media: | visual |
| Animatable: | yes |
For details refer to the CSS3 Text Module. Note that SVG does not allow the value "string" for this property, and that the values "left" and "right" have been replaced by the internationalized equivalents, "before" and "after".
Vertical alignment in flowing text is provided by the vertical-align property from CSS2.
| Value: | baseline | sub | super | top | text-top | middle | bottom | text-bottom | percentage | length | inherit |
| Initial: | baseline |
| Applies to: | text and flowText |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Animatable: | yes |
For details refer to the CSS2 specification.
As currently specified, the vertical-align property is unsatisfactory for vertical text. The SVG Working Group requests feedback on this topic.
Vertical alignment will also be available on normal text elements.
In the situations where the text and graphics associated with a flow do not fit into the defined regions an OverflowEvent is raised. The OverflowEvent contains information on the amount of text and graphics that could not be placed into the region.
The next draft of this specification will fully specify the behaviour of overflow.
Below is an example of the flowing text capabilities:
<svg xmlns:svg="http://www.w3.org/2000/svg" version="1.2"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 300 310">
<title>Basic textflow</title>
<rect x="0" y="0" width="100%" height="100%" fill="yellow"/>
<flow font-size="16">
<flowRegion>
<path d="M100,50L50,300L250,300L300,50z"/>
</flowRegion>
<flowDiv>
<flowPara>Tomorrow, and tomorrow, and tomorrow; creeps in this
petty pace from day to day, until the last syllable of recorded time.
And all our yesterdays have lighted fools the way to dusty death.
</flowPara>
</flowDiv>
</flow>
<path d="M90,40L40,270L260,270L210,40z" fill="none" stroke="black" stroke-width="5"/>
</svg>
View this image as SVG (SVG-enabled browsers only)
A more complicated example is show below. It is not included inline. Please see the SVG file for the source.
View this image as SVG (SVG-enabled browsers only)
There are many SVG use cases where textual input is a requirement. Implementing such a feature in SVG 1.1 with the DOM is nearly impossible without restricting functionality, such as only allowing latin left-to-right text.
SVG 1.2 introduces editable text fields, moving the burden of text input and editing to the user agent, which has access to system text libraries.
The text and flowDiv elements have an editable attribute which defines if the contents of the elements can be edited in place.
If set to "false" the contents of the text element are not editable in place through the user agent. If set to "true", the user agent must provide a way for the user to edit the content of the text element and all contained subelements which are not hidden (with visibility="hidden") or disabled (through the switch element or display="none"). The user agent must also provide a way to cut the selected text from the element and to paste text from the clipboard into the element. If no value is given for this attribute, the default value is "false". Animatable: Yes.
In general, user agents should allow for the inline WYSIWYG editing of text with a caret that identifies current position. They should also support system functions such as copy/paste and drag/drop if available.
For WYSIWYG editing the following functionality must be made available:
For devices without keyboard access, the equivalent system input methods should be used wherever possible to provide the functionality described above.
The content of the DOM nodes that are being edited should be live at all times and reflect the current state of the edited string as it being edited (except for the state associated with an Input Method Editor window).
To match the two states of editable text and flowText elements, SVG user agents that suppport CSS style sheets must support the ':edited' pseudo-class. It is used to style the currently editable text field. As such, it is equivalent to the following CSS selectors:
svg|text[editable='true']:focus svg|flowText[editable='true']:focus
The SVGSelection interface allows the user to obtain details on the current text selection. When the user selects some text in a text or flowRoot element, the SVGSelectionEvent event is dispatched to the top-level svg element.
interface SVGSelection
{
readonly attribute boolean active; // true if something is selected
readonly attribute string text;
readonly attribute dom::Element firstElement;
readonly attribute SVGElementInstance firstElementInstance;
// index in characer data for the first selected character
readonly attribute unsigned long firstIndex;
// index in character data for the first non-selected character
readonly attribute unsigned long lastIndex;
readonly attribute dom::Element lastElement;
readonly attribute SVGElementInstance lastElementInstance;
};
interface SVGSVGElement
{
....
readonly attribute SVGSelection selection;
};
// sent to the top-level svg element when selection changes in any way
interface SVGSelectionEvent : events::Event
{
};
The SVGSelectionEvent is named "SVGSelectionChanged".
SVG 1.2 adds the ability to associate behavior or extensions with arbitrary XML markup within an SVG file. This feature is referred to as Rendering Custom Content (RCC).
The RCC feature set is expected to be moved to a separate specification from the next publication of this document. Discussions are already under way to merge the functionality with the XML Binding Language (XBL) that has been implemented in some HTML browsers. This will not delay the SVG 1.2 specification, and will allow the features to be used in multiple document formats (including both SVG and XHTML). A new XBL specification is being developed by the SVG Working Group with liaison with other W3C Working Groups. It is highly likely that the first official W3C version of XBL will address the requirements of SVG 1.2, where future versions add some features needed by other document languages.
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:
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 handler 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 automatic cloning of the contents of the prototype child element or copying the tree generated by the XML transformer referenced by the transformer element, as well as DOM manipulation of the shadow tree via 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:choice minOccurs="0" maxOccurs="1">
<xs:element ref="prototype"/>
<xs:element ref="traitDef"/>
<xs:element ref="transformer"/>
</xs:choice>
<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 name attribute specifies the name of the element being defined.
The above schema may need to be modified to constrain the grammar so that only one prototype or transformer element can be specified.
An attribute which prevents initial shadow tree generation may be added to the elementDef 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.
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.
The transformer element is likely to be removed from the next draft of SVG 1.2, due to the high burden on implementation and the difficulty in optimization.
An XML transformer is something that takes XML as input, and produces XML as output, like an XSLT stylesheet. The transformerelement provides the ability to run a specified XML transformer with specified parameter values, and place the results onto the 'shadowTree' DOM property for the custom element. It is equivalent to the output of the transformation being placed as the literal content of a prototype element. In particular, if the XML transformer's output includes refContent or custom element output, then further shadow tree references are implicit in the output, just as they would be within a prototype element.
Suppose an elementDef is defined for a custom element, and that elementDef has a transformer child. If the custom element has an svg:input attribute (where the 'svg:' prefix is bound to the SVG namespace), then the input for the XML transformer is the XML tree specified by the svg:input attribute value, which is a URI. For example, this URI can point to:
If the custom element does not have an svg:input attribute then it behaves as if the svg:input attribute has a default value pointing to the custom element in question, meaning that the input for the XML transformer is the branch of the DOM rooted at this custom element.
When a custom element's shadow tree includes a refContent element, this refers to the shadow trees of the descendants of the custom element in question, regardless of whether the shadow tree was generated by a transformer element and regardless of whether the custom element has an svg:input attribute pointing elsewhere. The refContent mechanism is not used to recurse on the XML trees of external resources.
The transformation code specified by the transformer element is run on document load and every time there is a mutation anywhere in the document.
This idea of running a script or other process on a branch of an XML tree to produce a generated SVG sub-tree is not specific to XSLT, 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. Initially, we'll only deal with XSLT as the default and as top priority for implementers.
There is discussion of using an element like in or source rather than an attribute to provide the functionality of the svg:input attribute.
An attribute which prevents the svg:input from being usable with a particular custom element may added to the elementDef element.
The example below demonstrates a trivial use of the transformer element that draws red diamonds.
<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">
<extensionDefs id="shapes" namespace="http://foo.example.org/shapes">
<xsl:stylesheet id="diamond" 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">
<svg x="{@x}" y="{@y}" width="{@width}" height="{@height}"
viewBox="0 0 100 100">
<rect transform="rotate(44,50%,50%)"
fill="red"
width="100%"
height="100%"/>
</svg>
</xsl:template>
</xsl:stylesheet>
<elementDef name="diamond">
<transformer xlink:href="#diamond" type="text/xsl"/>
<elementDef>
</extensionDefs>
<foo:diamond x="10" y="10" width="30" height="30"/>
<foo:diamond x="50" y="15" width="25" height="25"/>
<foo:diamond x="5" y="20" width="25" height="10"/>
</svg>
The following is a schema snippet which defines the transformer element:
<element name="transformer">
<complexType>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="svg:param"/>
<!-- <group ref="svg:desc-title-metadata"/> -->
</choice>
<attribute ref="xlink:href" use="required"/>
<attribute name="type" type="string"/>
</complexType>
</element>
Attributes:
Mechanics for XSLT, which is the initial focus, are clear. URI syntax and invocation mechanics may also be added for Java and ECMAScript.
The param element passes string information to the XML transformer (such as XSLT), mimicking the information that could be passed on the command line to the XML transformer.
The name of the param element is not finalized. Other candidate names include with-param and withParam.
The example below demonstrates a trivial use of the param element.
<svg width="7cm" height="5cm" viewBox="0 0 70 50" version="1.2"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<extensionDefs id="shapes" namespace="http://foo.example.org/shapes">
<xsl:stylesheet id="light" 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:param name="lightcolor">
<xsl:template match="foo:description">
<!-- Strip out descriptions -->
</xsl:template>
<xsl:template match="foo:light">
<xsl:variable name="x" select="../@x" />
<xsl:variable name="y" select="../@y" />
<xsl:variable name="width" select="../@width" />
<xsl:variable name="height" select="../@height" />
<svg x="{$x}" y="{$y}" width="{$width}" height="{$height}"
viewBox="0 0 100 100">
<rect transform="rotate(44,50%,50%)"
stroke="black"
stroke-width="1"
width="100%"
height="100%"/>
<circle stroke="none" fill="{$lightcolor"}
cx="50%"
cy="50%"
r="25%"/>
</svg>
</xsl:template>
</xsl:stylesheet>
<elementDef name="stop">
<transformer xlink:href="#light" type="text/xsl">
<param name="lightcolor" value="red"/>
</transformer>
<elementDef>
<elementDef name="go">
<transformer xlink:href="#light" type="text/xsl">
<param name="lightcolor" value="green"/>
</transformer>
<elementDef>
<elementDef name="gofast">
<transformer xlink:href="#light" type="text/xsl">
<param name="lightcolor" value="yellow"/>
</transformer>
<elementDef>
</extensionDefs>
<foo:stop x="10" y="10" width="30" height="30" >
<foo:description>A "stop" with a light</foo:description>
<foo:light/>
</foo:stop>
<foo:gofast x="50" y="15" width="25" height="25" >
<foo:description>A "gofast" with a light</foo:description>
<foo:light/>
</foo:gofast>
<foo:go x="5" y="20" width="25" height="10" >
<foo:description>A "go" with a light</foo:description>
<foo:light/>
</foo:go>
</svg>
The following is a schema snippet which defines the param element:
<element name="param">
<complexType>
<attribute name="name" type="NMTOKEN" />
<attribute name="value" type="string" use="required"/>
</complexType>
</element>
Attribute definitions:
The param element binding with XSLT is fairly clear. The binding for Java and perhaps also ECMAScript needs to be specified.
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
A trait is a potentially animatable parameter associated with an element. A trait is the value that gets assigned through an XML attribute or CSS style or SMIL animation. In the case of RCC, it describes an attribute on a custom element, allowing it to be exposed to the animation engine.
Traits for custom elements are described using the traitDef element.
<xs:element name="traitDef">
<xs:complexType>
<xs:sequence>
<xs:attribute name="name" use="required" />
<xs:attribute name="namespace" use="required" />
<xs:attribute name="type" use="required" />
<xs:attribute name="valueType" use="required" />
</xs:sequence>
</xs:complexType>
</xs:element>
The name and namespace attributes respectively specify the name and namespace of the attribute.
The type attribute is similar to the corresponding type attribute from animation elements. It allows the values "CSS" and "XML". The default is "XML".
The valueType attribute specifies the type of the attribute. It only supports existing values, such as "SVGMatrix", "SVGLength", etc.
Need to define exact list of valueTypes.
Below is an example that defines traits for the x, y, width and height attributes for a custom foo:button element.
<elementDef name="button" namespace="http://www.example.com/foo">
<traitDef name="x" valueType="SVGLength"/>
<traitDef name="y" valueType="SVGLength"/>
<traitDef name="width" valueType="SVGLength"/>
<traitDef name="height" valueType="SVGLength"/>
<prototype>
....
</prototype>
</elementDef>
Shadow tree generation occurs initially when the document is loaded. Shadow tree generation also occurs when a custom element is added to the SVG document via DOM.
Subsequent regeneration of shadow tree for particular elements may be triggered by a declaratively specified set of events.
Declarative syntax for specifying the set of events that cause a particular element's shadow tree to be regenerated hasn't yet been developed. It may be a SMIL like list of events (the "begin" and "end" animation timing attributes can take an event list) or use some sort of XML event listener syntax.
The default (perhaps empty) set of events that cause shadow tree regeneration is to be determined.
In addition an attribute may be set that causes the UA to regenerate shadow trees every time there is a modification to the DOM that may affect the shadow tree.
Declarative syntax for specifying the above attribute hasn't yet been developed. It's default value is to be determined. In addition, what "a modification to the DOM that may affect the shadow tree" means needs to be tightly specified.
In addition, there is a DOM call "rebind()" that causes regeneration of the shadow tree for a particular element.
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).
The 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 ... ;
void rebind() 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.
Two new events are defined to support the RCC feature set: SVGBindBegin and SVGBindEnd. SVGBindBegin is fired before the user agent creates the shadow tree for a custom element. SVGBindEnd is fired when the user agent has finished adding the element's shadow tree to the element and after any custom elements in the shadow tree have been processed.
Initial processing of custom elements is done in document order (preorder depth first traversal of the tree). This means that initially, a custom element's SVGBindBegin must be fired before the element's descendants shadow trees have been created and therefore before any of the descendants' SVGBindBegin and SVGBindEnd events have been fired. For progressive rendering, a custom element's SVGBindBegin may not be fired until the custom element's end tag has been read.
Regeneration of a custom element's shadow tree causes SVGBindBegin and SVGBindEnd events to be fired.
The two new event types extend dom::Event. The event target is the custom element.
In order to ensure interoperability:
Any script elements inside of extensionDefs elements 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.) Any handler elements inside of extensionDefs elements which 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.
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.
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.
Resolution: regeneration of shadow tree is triggered via event handling/listener which is manually established using XML event listeners.
Resolution: the feature will use XML events for event handling.
Resolution: the current approach seems to cover most situations in both cases.
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.
The working group is still working on this aspect of the feature.
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.
The working group is still working on this aspect of the feature.
The working group is still working on this aspect of the feature.
Resolution: no, we aren't just going to add new options to the use element.
The working group is still working on this aspect of the feature.
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.
Suggested resolution: no, shadow tree elements are owned by document with the custom element, not the document with the custom element's elementDefs
Suggested resolution: no.
Below is 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>
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>
<handler ev:event="SVGBindEnd" type="text/ecmascript"><![CDATA[
var svgns = "http://www.w3.org/2000/svg";
var xlinkns = "http://www.w3.org/1999/xlink";
var flowchartns = "http://example.org/rcc-flowcharts";
var ELEMENT_NODE = 1;
var SIDE_INDENT = 50;
var PROCESSNODE_WIDTH = 150;
var TERMINALNODE_WIDTH = 100;
var CONNECTOR_WIDTH = 100;
var 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++;
}
}
]]></handler>
</elementDef>
</extensionDefs>
</svg>
The next example 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.
<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>
The next example 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>
The next example 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>
The last example shows RCC being used for custom container elements that perform layout, in this case a magazine layout.
<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>
XForms is a technology for describing forms in XML. It separates the model, or the information that is to be sent as the result of the form, from the abstract controls that will be used to get information from the person using the form. XForms deliberately says nothing about presentation of form controls; this is left to a styling or transformation language, to generate the actual visual (or indeed, audio) form widgets. XForms cannot be used by itself; it is designed to be integrated into a host language, such as SVG. This provides the host language with an abstract definition of form content and leaves the rendering to the host. SVG is well suited to hosting XForms, since it provides powerful rendering and interactivity APIs.
Furthermore, a generic set of user interface components has been a common request from the SVG community. By describing how SVG and XForms can be integrated that request can be answered while providing more functionality if required. For example, the tight integration with a data model of a form should allow an SVG/XForms implementation to package SOAP messages easily. It also would allow an author to provide multiple interfaces to the same form (SVG, CSS, VoiceXML).
It also should be possible to extend generic form controls to use an SVG rendering specified by the document author. Events within the SVG rendering should be linked to behavior that updates the form model.
At the time of publication, the Working Group is undecided as to whether or not the SVG specification should describe a default rendering and behavior for some form elements, such as buttons and sliders. We realize that creating widget sets is a deep topic and specifically request feedback on this matter. Would a simple set of form widgets be sufficient in most situations, or would authors prefer to always create the SVG rendering and behavior for every element?
Readers will notice the RCC section makes a number of references to XForms. The current feeling of the Working Group is enable XForms through this feature and by adding a small number of low-level widgets to the SVG language (such as text-entry).
In many cases, such as text editing, the user is required to place focus on a particular element, ensuring that input events, such as keyboard input, are sent to that element.
| Value: | "true" | "false" | "auto" |
| Initial: | "auto" |
| Applies to: | container elements and graphics elements |
| Inherited: | no |
| Percentages: | N/A |
| Media: | visual |
| Animatable: | yes |
The focusable property determines if an element can get keyboard focus (i.e. receive keyboard events) and participate in the "tab order". The value "true" means that the element is keyboard-aware and should be treated as any other UI component that can get focus. The value "false" means that it should not. The value "auto" is equivalent to "false", except that it acts like "true" for the following cases:
By default, the tab key navigates between elements that can obtain focus (ie. elements for which the value of the focusable property evaluates to "true").
In the author wishes to change the default tab order, they must catch the input event related to the navigation (such as the tab keypress) and then cancel the event.
Navigation order is determined using the nav-index property from the CSS 3 Basic User Interface Module. In most cases, the value 'auto' will cause the user agent to use document order for navigation order. This property only applies to focusable elements.
Keyboard equivalents can be assigned to focusable elements using the key-equivalent property from the CSS 3 Basic User Interface Module. This property only applies to focusable elements.
When the user agent gives an element focus it receives a DOMFocusIn event.
The SVGElement and SVGElementInstance interfaces have a focus() method that, when called, requests that the User Agent give focus to the particular element. Calling focus() on an element that is not focusable has no effect.
Should this be the case? Should the focus() API ignore the property?
The SVGDocument interface have next() and previous() methods which move the focus onto the respectively next or previous focusable element.
The following open issues are yet to be discussed:
The SVG 1.1 language does not specify a method for the declarative display of tooltips on SVG content. While it suggests that the content of the title element could be displayed as a tooltip, it does not provide any control for the content developer. This meant that developers resorted to implementing their own tooltip functionality using scripting.
SVG 1.2 adds declarative tooltip support through the tooltip property. This allows for the display of textual tooltips to be declaratively controlled for each element in the SVG document. User agents should use the platform tooltip system if there is one available. On platforms without native support for tooltips, user agents can implement their own tooltip system. This means that the appearance, position and behavior of the tooltip is implementation or platform specific.
However, in the visual environment, the user agent must attempt to display the entire tooltip in a readable manner, avoiding clipping by the edge of the device or canvas. If possible the tooltip should be implemented as a temporary graphic that is superimposed on the top of the SVG canvas at the location of the pointer if one exists. Also, if possible, the content of the tooltips should be made available to accessibility implementations on the device.
The SVG Working Group plans to add a feature to provide enhanced floating windows above the canvas, which would allow for more graphically rich tooltips. This may not be tied to the tooltip property, which provides the common functionality. That is, rich floating graphics are not considered tooltips for now.
The hint element is another level of metadata for an element. The contents of the hint element are intended to be displayed by a tooltip. It differs from the title and desc elements in that a hint may give instructions to the user, as opposed to describe the element that it belongs to.
<svg xmlns="http://www.w3.org/2000/svg" version="1.2">
<circle cx="50" cy="50" r="25" fill="red" tooltip="enable">
<title>The target area</title>
<hint>Click here to start the animation</hint>
<animate .... />
</circle>
</svg>
The following is an extract of the schema that describes the hint element:
<xs:element name="hint">
<xs:complexType mixed="true">
<!-- any attributes? -->
</xs:complexType>
</xs:element>
The tooltip property specifies whether or not tooltips should be displayed for this element.
| Value: | enable | disable | inherit |
| Initial: | enable |
| Applies to: | graphics and container elements |
| Inherited: | yes |
| Percentages: | N/A |
| Media: | visual |
| Animatable: | yes |
If the tooltip property is set to "enable" then the content of the tooltip is the text content of the hint child of an element. For elements that do not have a hint child, the tooltip content is the content of its parent's tooltip. If the tooltip property is set to "disable" then the content of the tooltip is empty. The value of the tooltip for a root svg element without a hint child is empty. In the case of an empty value, the tooltip will not be displayed.
Tooltips and the CSS hover property both track the mouseover and mouseout events. Tooltips may require the pointer to be stationary over the target for a short period of time. Tooltips and hover represent additive effects. The hover processing should occur first followed by tooltip processing. That is, tooltip processing is placed after hover processing and before hyperlink processing. Tooltips respond to pointer events in the same manner as hover, thus do not activate on elements with either the display or pointer-events properties set to "none".
XML Events is an XML syntax for integrating event listeners and handlers with DOM Event interfaces. Declarative event handling in SVG 1.1 is hardwired into the language, in that the developer is required to embed the event handler in the element syntax (e.g. an element has an onclick attribute). SVG 1.2 adds support for XML Events, providing the ability to listen to custom events, as well as specifying the event listener separately from the graphical content.
SVG 1.2 makes the following modifications to XML Events:
The following is an example of an SVG file using XML Events:
<svg xmlns="http://www.w3.org/2000/svg" version="1.2"
xmlns:ev="http://www.w3.org/2001/xml-events">
<rect id="myRect" x="10" y="20" width="200" height="300"
fill="red"/>
<!-- register a listener for a myRect.click event -->
<ev:listener ev:event="click" ev:observer="myRect"
ev:handler="#myClickHandler" />
<handler id="myClickHandler" type="text/ecmascript">
var myRect = document.getElementById("myRect");
var width = parseFloat(myRect.getAttribute("width"));
myRect.setAttribute("width", (width+10));
</handler>
</svg>
In the above example, the ev:listener element registers that the myClickHandler element should be invoked whenever a "click" event happens on "myRect".
The handler element has been added to SVG 1.2 and is described in the following section.
The combination of the XML Events syntax and the new handler element allows event handling to be more easily processed in a compiled language. Below is an example of an event handler using the Java language:
<svg xmlns="http://www.w3.org/2000/svg" version="1.2"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:foo="http://www.example.com/foo">
<rect id="myRect" x="10" y="20" width="200" height="300"
fill="red"/>
<!-- register a listener for a myRect.click event -->
<ev:listener ev:event="click" ev:observer="myRect"
ev:handler="#myClickHandler" />
<handler id="myClickHandler" type="application/java"
xml:base="http://example.com/myJar.jar"
xlink:href="#com.example.MyXMLEventHandler"/>
<foo:offset>10</foo:offset>
</handler>
</svg>
In this case, the handler element specifies the location of compiled code that conforms to the XMLEventHandler interface. The user agent invokes the handleEvent method within the targeted interface.
In this case, the MyXMLEventHandler has the following definition:
package com.example;
import org.w3c.svg.XMLEventHandler;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.events.Event;
public class MyXMLEventHandler implements XMLEventHandler {
Document document;
public void init(Document doc, Element handlerElement) {
document = doc;
// ...
}
public void handleEvent(Event event) {
Element myRect = document.getElementById("myRect");
float width = Float.parseFloat(myRect.getAttribute("width"));
myRect.setAttribute(width, "" + (width + 10));
}
}
The XMLEventHandler interface has been temporarily placed in the SVG package/namespace. The SVG Working Group will liaise with the HTML Working Group to provide an interface for this class.
The definition of the XMLEventHandler Interface is shown below:
/**
* XMLEventHandler
*/
interface XMLEventHandler extends org.w3c.dom.events.EventHandler {
/**
* Gives the handler an opportunity to do any type of
* initialization it requires.
* This should be called before the onload event is
* dispatched on the Document.
*
* @param doc reference to the Document this handler is
* attached to
* @param handler reference to the handler element
*/
void init(in Document doc, in Element handler);
}
The handler element is similar to the script element: its contents, either included inline or referenced, are code that is to be executed by the scripting engine(s) used by user agent.
However, where the script element evaluates its contents when the document is loaded, the handler element evaluates its contents in response to a event. This makes handler functionally equivalent to using the event attributes.
For example, consider the following SVG 1.1 document:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect id="myRect" x="10" y="20" width="200" height="300" fill="red"
onclick="var width = parseFloat(
document.getElementById('myRect').getAttribute('width'));
document.setAttribute('myRect', 'width', (width+10));"/>
</svg>
The above example can be rewritten to use the handler element and XML Events (described below) as shown:
<svg xmlns="http://www.w3.org/2000/svg" version="1.2"
xmlns:ev="http://www.w3.org/2001/xml-events">
<rect id="myRect" x="10" y="20" width="200" height="300" fill="red">
<handler type="text/ecmascript" ev:event="click">
var myRect = evt.target;
var width = parseFloat(myRect.getAttribute("width"));
myRect.setAttribute("width", (width+10));
</handler>
</rect>
</svg>
In ECMAScript, the contents of the handler element behave as if they are the contents of a new function object, created as shown:
function(evt) {
// contents of handler
}
Other interpreted languages behave in as similar a manner as possible.
The 'evt' parameter shown above is an Event object corresponding to the event that has triggered the handler.
The following is a schema extract which defines the handler element:
<xs:element name="handler">
<xs:complexType>
<xs:attributeGroup ref="commonAttrs"/>
<xs:attribute name="type" use="required"/>
<xs:attribute ref="xlink:href"/>
<xs:attribute ref="ev:event"/>
</xs:complexType>
</xs:element>
Attributes:
For compiled languages, the xlink:href attribute has the same meaning as the combination of the classid and codebase attributes in HTML 4.01. The reference must resolve to a class that implements the XMLEventHandler interface (described below).
In many situations, the script author uses the handler as a template for calling other functions, using the content of the handler element to pass parameters. However, for compiled languages the handler element does not have any executable content.
In this case, the author should embed the parameters into the handler as custom content. The execution of the handler code retrieves the contents of the parameters using the DOM.
Below is an example of using parameters on the handler element:
<svg xmlns="http://www.w3.org/2000/svg" version="1.2"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:foo="http://www.example.com/foo">
<rect id="myRect" x="10" y="20" width="200" height="300"
fill="red"/>
<!-- register a listener for a myRect.click event -->
<ev:listener ev:event="click" ev:observer="myRect"
ev:handler="#myClickHandler" />
<handler id="myClickHandler" type="application/java"
xlink:href="http://example.com/myJar.jar#com.example.MyXMLEventHandler"/>
<foo:offset value="10"/>
<foo:person>
<foo:name>Victor Vector</foo:name>
<foo:age>42</foo:age>
</foo:person>
</handler>
</svg>
In this case, the object com.example.MyXMLEventHandler has its handleEvent method called whenever a 'click' event on the 'myRect' object is observed. The object can then retrieve the children of the handler element in order to obtain the contents of the elements from the "foo" namespace.
SVG 1.0 used SMIL Animation for its animation syntax. It has been a common request from the public to have more features from SMIL in SVG. For that reason, SVG 1.2 will mostly likely incorporate more of SMIL 2.0. In this document the audio, video and some timing elements are described. Future revisions will expand on the SMIL integration.
The current proposal is to add more SMIL elements into the SVG language. Alternatively, the SVG Working Group may produce a W3C Note which defines an SVG+SMIL profile, similar to the XHTML+SMIL profile.
It is worth noting what parts of SMIL 2.0 are not under consideration for SVG 1.2. SVG would probably not include SMIL Layout, Linking, Structure and MetaInformation.
The audio element specifies an audio file which is to be rendered to provide synchronized audio. The usual SMIL animation features are used to start and stop the audio at the appropriate times. An xlink:href is used to link to the audio content. No visual representation is produced. However, content authors can if desired create graphical representations of control panels to start, stop, pause, rewind, or adjust the volume of audio content.
It is an open questio