During the later stages of the SVG Mobile 1.1 specification it became obvious that there was a requirement to subset the SVG and XML DOM in order to reduce the burden on implementations. SVGT 1.2 adds new features to the uDOM, allowing for as much necessary functionality as possible, still being suitable for SVG Tiny implementations.
Furthermore, it should be possible to implement the uDOM on devices that support SVG Tiny 1.1 although, in this case, the scripting would be external to the SVG document (since SVG Tiny 1.1 does not support inline scripting).
The goal of the uDOM definition is to provide an API that allows access to initial and computed attribute and property values, to reduce the number of interfaces, to reduce run-time memory footprint using necessary features of the core XML DOM, as well as the most useful SVG features (such as transformation matrices).
The IDL definition for the uDOM is provided.
This appendix consists of the following parts:
The following sections describe the SVG uDOM key features and constraints.
Note. Like other W3C DOM definitions, the SVG uDOM is programming-language independent. Although this appendix only contain ECMAScript and Javatm language examples, the SVG uDOM is compatible with other programming languages.
The SVG uDOM offers access to
Document object which is the root for accessing other features. The way the
Document object becomes available depends on
the usage context. One way to gain access to the
Document object is to implement the
EventListenerInitializer2 interface. The SVG Tiny user agent will invoke the implementation's initializeEventListeners
(dom::Document doc)
method once the programming logic has been loaded and is ready to bind to the
document. The Document object
is sometimes accessible through other means, for example as the
global 'document' variable in ECMAScript.
SVG uDOM only allows navigation of the element nodes in the DOM tree. Two options are available for navigating the hierarchy of elements:
getElementById
method on the Document interface.
parentNode
attribute on the Node interface.
The ElementTraversal interface provides firstElementChild
,
lastElementChild
, previousElementSibling
and
nextElementSibling
, which are particularly suitable for constrained devices. These traversal mechanisms skip over intervening nodes between element nodes, such as text nodes which might only contain spaces, tabs and newlines.
SVG uDOM allows the creation of new
Elements:
Element myRect = document.createElementNS(svgNS, "rect");
Node Addition is the ability to add new elements to a document tree.
SVG uDOM allows addition and insertion of a
Node:
String svgNS = "http://www.w3.org/2000/svg";
// Create a new <rect> element
Element myRect = document.createElementNS(svgNS, "rect");
// Set the various <rect> properties before appending
...
// Add element to the root of the document
Element svgRoot = document.getDocumentElement();
svgRoot.appendChild(myRect);
// Create a new <ellipse> element
Element myEllipse = document.createElementNS(svgNS, "ellipse");
// Set the various <ellipse> properties before insertion
...
// Insert the ellipse before the rectangle
svgRoot.insertBefore(myEllipse, myRect);
Node removal is the ability to remove an element from a document tree. SVG uDOM allows the removal of element Nodes.
Element myRect = ...; // See Element creation
Element myGroup =document.getElementById("myGroup");
myGroup.appendChild(myRect);
....
myGroup.removeChild(myRect);
SVG 1.2 adds a new ability to access XML attribute andCSS property values through the SVG uDOM through the concept of Traits. A trait is a potentially animatable parameter associated with an element. Trait is the typed value (e.g., a number, not just a string) that gets assigned through an XML attribute or a CSSproperty. Traits can be thought of as a unification and generalization of some of the notions of XML attributes and CSS properties.
The trait facilities in the SVG uDOM allow for strongly-typed access to
certain attribute and property values. For example, there is a
getFloatTrait(...)
method for getting an attribute or property value
directly as a float. This contrasts the DOM Core getAttributeNS(...)
method which always returns a string.
The trait facilities in the SVG uDOM are available on the TraitAccess interface.
float width = myRect.getFloatTrait('width');
width += 10;
myRect.setFloatTrait('width', width);
SVG uDOM provides restricted access to attributes via getAttributeNS
and setAttributeNS
on the Element interface. The
restrictions are described in
getAttributeNS
.
In the SVG uDOM, text node access is available via trait getters and setters and via
the textContent attribute on the
Node interface.
To access or set the text string value for an element via traits you
invoke getTrait()
or
setTrait()
on that element and pass #text
as
the name of the trait you want to get or set. For example,
MyTextElement.setTrait("#text", "Hello");
Text access via the #text mechanism is supported on Text Content, 'desc', 'title' and 'metadata' elements. Text access to other elements defined within this specification (see list of elements) is not supported and an implementation is free to ignore any text on these elements.
The result of getting and setting text content via the #text mechanism is exactly the same as when using the textContent attribute. Therefore the user should be aware of the fact that styling by 'tspan' elements will be lost if she gets a text string from the model and sets it back again.
Event Listener Registration and Removal is the ability to add and remove new event listeners from a Document. SVG uDOM allows adding and removing EventListeners:
class MyEventListener implements EventListener {
public void handleEvent(Event evt) {
// Do whatever is needed here
}
}
...
EventListener l = new MyEventListener();
SVGElement myRect = (SVGElement)document.getElementById("myRect");
//Listen to click events, during the bubbling phase
myRect.addEventListener("click", l, false);
....
// Remove the click listener
myRect.removeEventListener("click", l, false);
The SVG uDOM only supports the bubble phase. Any attempt to specify event operations on the capture phase will raise a DOMException of type NOT_SUPPORTED_ERR.
Refer to the DOM Events Level 3 specification or the XML Events specification introduction for an explanation of the SVG event flow and the meaning of event targets, event current target, bubble and capture.
SVG uDOM allows code to start or end animation elements.
AnimationElement animateColor = (AnimationElement) document.getElementById("myAnimation");
// Start the animation 2.5 seconds from now.
animateColor.beginElementAt(2.5);
The SVG uDOM will use the same package names as the SVG 1.2 Full DOM (e.g., org.w3c.dom,org.w3c.dom.events, org.w3c.dom.svg). This allows applications which restrict themselves to the features in the SVG uDOM to also run in implementations that support the SVG 1.2 Full DOM.
exception DOMException { unsigned short code; }; // ExceptionCode const unsigned short WRONG_DOCUMENT_ERR = 4; const unsigned short INDEX_SIZE_ERR = 1; const unsigned short HIERARCHY_REQUEST_ERR = 3; const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7; const unsigned short NOT_FOUND_ERR = 8; const unsigned short NOT_SUPPORTED_ERR = 9; const unsigned short INVALID_STATE_ERR = 11; const unsigned short INVALID_MODIFICATION_ERR = 13; const unsigned short INVALID_ACCESS_ERR = 15; const unsigned short TYPE_MISMATCH_ERR = 17;
This interface is a subset of the Node interface defined in the DOM Level 3 Core. The only node types that are required to be supported in the uDOM are Element nodes and Document nodes.
interface Node { readonly attribute DOMString namespaceURI; readonly attribute DOMString localName; readonly attribute Node parentNode; readonly attribute Document ownerDocument; attribute DOMString textContent; Node appendChild(in Node newChild) raises(DOMException); Node insertBefore(in Node newChild, in Node refChild) raises(DOMException); Node removeChild(in Node oldChild) raises(DOMException); };
null
is returned.
Node
of this Node
.
This attribute returns the text content of this node and its descendants. When it is defined to be null, setting it has no effect. On setting, any possible children this node may have are removed and, if it the new string is not empty or null, replaced by a single Text node containing the string this attribute is set to. On getting, no serialization is performed, the returned string does not contain any markup. No whitespace normalization is performed and the returned string does not contain the white spaces in element content. Similarly, on setting, no parsing is performed either, the input string is taken as pure textual content.
textContent
is supported on all non-svg elements. For elements defined
within this specification (see list of elements)
textContent
is supported on the
Text Content,
'desc',
'title'
and 'metadata' elements.
textContent
on a non-supported element is null. Setting textContent
on a non-supported element has no effect.
textContent
on the document
node is always null.
An alternate way of accessing text content on elements defined within the svg specification is via the getTrait("#text") syntax.
For further details see DOM3 textNode.
Node
.
Node
to be appended to this
Node
. This is equivalent to insertBefore(newChild,null)
Node
that is to be removed.
The SVG WG has considered to not allow removal of elements that are referenced by other elements. The WG has resolved to not add this constraint but are willing to reconcider if implementation feedback shows that such a constraint would decrease implementation cost. With such a constraint, calling removeChild on a referenced element would not remove the element and the method would raise a DOMException (INVALID_ACCESS_ERR).
interface Element : Node { DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException); void setAttributeNS(in DOMString namespaceURI, in DOMString localName, in DOMString value); };
Retrieves an attribute value by local name and namespace URI. Per [XML Namespaces], applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace.
A uDOM implementation must support getAttributeNS for all
attributes on elements that does not belong to
SVGT1.2 [List of SVGT1.2 Elements]. For
attributes belonging to SVGT1.2 [List of SVGT1.2 Attributes]
the implementation must support attributes accessible by the getTrait method on SVGElement
(see table for
list of attributes supporting getTrait).
An important difference between getTraitNS and getAttributeNS is that
getTraitNS returns the computed attribute value but getAttributeNS
returns the specified attribute value (witch might not exactly match the original specified value due to the possibility of user agent value normalization as described below).
<g fill="red">
<rect id="r1" x="1" y="1" width="5" height="5"/>
<rect id="r2" fill="inherit" x="1" y="1" width="5" height="5"/>
</g>
r1.getTraitNS(svgNS, "fill")
return "red". (or equivalent normalized form, see below)
r2.getTraitNS(svgNS, "fill")
return "red". (or equivalent normalized form, see below)
r1.getAttributeNS(svgNS, "fill")
return "".
r2.getAttributeNS(svgNS, "fill")
return "inherit".
A viewer implementing the UDOM is allowed to return normalized values in getAttributeNS as defined
in DOM 3.
E.g. fill="red" may be returned as "rgb(255,0,0)", "#ff0000", or other semantically identical form.
stroke-width="3" might be returned as e.g. "3.00".
Adds a new attribute. The value to set is a simple string; it is not parsed as it is being set. So any markup is treated as literal text, and needs to be appropriately escaped by the implementation when it is written out. Per [XML Namespaces], applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace.
A uDOM implementation must support setAttributeNS for all attributes.
This interface is a subset of the Document interface defined in the DOM Level 3 Core.
Note the behavior of the following attributes and methods from the
Node
interface when called on a Document
object:
null
HIERARCHY_REQUEST_ERR
HIERARCHY_REQUEST_ERR
NOT_SUPPORTED_ERR
interface Document : Node { Element createElementNS(in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException); readonly attribute Element documentElement; Element getElementById(in DOMString id); };
SVGSVGElement
, but return
type is Element for DOM Core compatibility and to allow for future extensions.
Element
based on the specified
(qualified) tag name.
Element
in the current document with
the given unique ID. If no such element exists, this returns null.
If more than one element has an ID attribute with that value, this method
returns the first element, in document order, which has the requested ID.
interface EventTarget { void addEventListenerNS(in DOMString namespaceURI, in DOMString type, in EventListener listener, in boolean useCapture); void removeEventListenerNS(in DOMString namespaceURI, in DOMString type, in EventListener listener, in boolean useCapture); };
This interface must be implemented and registered on an EventTarget using the EventTarget#addEventListenerNS method to be notified about events that occur on or bubble through the event target.
interface EventListener { void handleEvent(in Event evt); };
interface Event { readonly attribute EventTarget target; readonly attribute EventTarget currentTarget; readonly attribute DOMString type; };
interface OriginalEvent { readonly attribute Event originalEvent; };
interface MouseEvent : Event { readonly attribute long screenX; readonly attribute long screenY; readonly attribute long clientX; readonly attribute long clientY; readonly attribute unsigned short button; };
Event type that is a Text Event: textInput.
interface TextEvent : Event { readonly attribute DOMString data; };
Event types that are Keyboard Events: keyDown, keyUp.
interface KeyboardEvent : Event { readonly attribute DOMString keyIdentifier; };
Event type that is a Connection Event: connectionData.
interface ConnectionEvent : Event { readonly attribute DOMString data; };
Event types that are TimeEvents: beginEvent, endEvent, repeatEvent.
interface TimeEvent : Event { readonly attribute long detail; };
Many devices today have a rotational input method, such as the wheel on a mouse or the "jog dial" of a phone or PDA.
The "wheel" event is triggered when the user rotates the rotational input device. This event may only be registered on the root-most svg element.
Event type that is a WheelEvent: wheel.
interface WheelEvent : Event { readonly attribute int wheelDelta; };
A "click" is defined to be a unit of rotation. On some devices this is a finite physical step. On devices with smooth rotation, a "click" becomes the smallest measurable amount of rotation.
Many resources, such as raster images, movies and complex SVG content can take a substantial amount of time to download. In some use cases the author would prefer to delay the display of content or the beginning of an animation until the entire contents of a file have been downloaded. In other cases, the author may wish to give the viewer some feedback that a download is in progress (e.g. a loading progress screen).
The ProgressEvent occurs when the user agent makes progress loading a resource (local or external) referenced by an xlink:href attribute.
The user agent must dispatch a ProgressEvent at the beginning of a load operation (i.e., just before starting to access the resource). This event is of type 'preload'. The value of the 'preload' event's progress property is 0.
The user agent must dispatch a ProgressEvent at the end of a load operation (i.e. after load is complete and the user agent is ready to render the corresponding resource). This event is of type 'postload' event. The value of the 'postload' event's progress property is 1.
The user agent may dispatch a loadProgress event between the 'preload' event and the 'postload' events. Such events are of type 'loadprogress'.
All 'loadprogress' events must follow to the following constraints:
In the case where the size of the downloading resource is known, such as from HTTP headers, then the progress property reflects the proportion of the current download that has been completed.
In the case where the size of the downloading resource is not known, then the progress property will only ever have the value 0 or 1.
The ProgressEvent has three corresponding event attributes on elements: onpreload, onpostload and onloadprogress.
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script type="application/ecmascript"><![CDATA[
function showImage(imageHref) {
var image = document.getElementById('myImage');
image.setTraitNS("http://www.w3.org/1999/xlink", "href", imageHref);
}
function imageLoadStart(evt) {
var progressBar = document.getElementById('progressBar');
progressBar.setFloatTrait("width", 0);
var loadAnimation = document.getElementById('loadAnimation');
loadAnimation.beginElement();
}
function imageLoadProgress(evt) {
var progressBar = document.getElementById('progressBar');
progressBar.setFloatTrait("width", 100*evt.progress);
}
function imageLoadComplete(evt) {
var progressBar = document.getElementById('progressBar');
progressBar.setFloatTrait("width", 100);
var loadAnimation = document.getElementById('loadAnimation');
loadAnimation.endElement();
}
]]></script>
<image id="myImage" xlink:href="imageA.png" width="300" height="400">
<handler type="application/ecmascript" ev:event="preload">
imageLoadStart(evt);
</handler>
<handler type="application/ecmascript" ev:event="loadprogress">
imageLoadProgress(evt);
</handler>
<handler type="application/ecmascript" ev:event="postload">
imageLoadComplete(evt);
</handler>
</image>
<rect width="120" height="30" y="400">
<handler type="application/ecmascript" ev:event="click">
showImage('imageB.png');
</handler>
</rect>
<animate id="loadAnimation" ... />
<rect id="progressBar" ... />
</svg>
Event types that are ProgressEvents: loadprogress, preload, postload.
interface ProgressEvent : Event { readonly attribute boolean lengthComputable; readonly attribute DOMString typeArg; readonly attribute unsigned long loaded; readonly attribute unsigned long total; };
interface ElementTimeControl { void beginElementAt(in float offset); void beginElement(); void endElementAt(in float offset); void endElement(); void pauseElement(); void resumeElement(); readonly attribute boolean isPaused; };
interface Global { };
interface Connection : events::EventTarget { typedef dom::DOMString DOMString; typedef dom::DOMException DOMException; void connect(in DOMString uri) raises(DOMException); void send(in DOMString data); void close(); readonly attribute boolean connected; };
exception SVGException { unsigned short code; }; // ExceptionCode const unsigned short SVG_INVALID_VALUE_ERR = 1; const unsigned short SVG_MATRIX_NOT_INVERTABLE = 2;
interface SVGDocument : Document, events::EventTarget { readonly attribute SVGGlobal global; };
For each 'use' element, the UDOM represents the referenced content with a shadow tree of SVGElementInstance objects (the "instance tree") of type SVGElementInstance. An SVGElementInstance represents a single node in the instance tree.
If the 'use' element references a simple graphics element such as a 'rect', then there is only a single SVGElementInstance object, and the correspondingElement attribute on this SVGElementInstance object is the SVGElement that corresponds to the referenced 'rect' element.
If the 'use' element references a 'g' which contains two 'rect' elements, then the instance tree contains three SVGElementInstance objects, a root SVGElementInstance object whose correspondingElement is the SVGElement object for the 'g', and then two child SVGElementInstance objects, each of which has its correspondingElement that is an SVGElement object representing the 'rect'. Note however that the uDOM does not provide methods to navigate between a SVGElementInstance and its children SVGElementInstances.
interface SVGElementInstance : events::EventTarget { readonly attribute SVGElement correspondingElement; readonly attribute SVGElement correspondingUseElement; };
This interface represents <svg> element in (SVG) document tree.
The DOM attributes currentScale, currentRotate and currentTranslate are combined to form user agent transformation which is applied at the outermost level on the SVG document (i.e., outside the outermost 'svg' element) if "magnification" is enabled (i.e., zoomAndPan attribute is set to "magnify"). Their values can potentialy be modified through user-agent specific UI. User agent transformation can be obtained by multiplying matrix
[currentScale 0 currentTranslate.x] [cos(currentRotate) -sin(currentRotate 0] [ 0 currentScale currentTranslate.y] by [sin(currentRotate) cos(currentRotate) 0] [ 0 0 1 ] [ 0 0 1]
i.e. (translate, then scale, then rotate the coordinate system). The reference point for scale and rotate operations is the origin (0, 0).
interface SVGSVGElement : SVGLocatableElement : SVGAnimationElement { const unsigned short FOCUS_AUTO = 1; const unsigned short FOCUS_NEXT = 2; const unsigned short FOCUS_PREV = 3; const unsigned short FOCUS_NORTH = 4; const unsigned short FOCUS_NORTH_EAST = 5; const unsigned short FOCUS_EAST = 6; const unsigned short FOCUS_SOUTH_EAST = 7; const unsigned short FOCUS_SOUTH = 8; const unsigned short FOCUS_SOUTH_WEST = 9; const unsigned short FOCUS_WEST = 10; const unsigned short FOCUS_NORTH_WEST = 11; attribute float currentScale; attribute float currentRotate; readonly attribute SVGPoint currentTranslate; readonly attribute SVGRect viewport; attribute float currentTime; SVGMatrix createSVGMatrixComponents(in float a, in float b, in float c, in float d, in float e, in float f); SVGRect createSVGRect(); SVGPath createSVGPath(); SVGRGBColor createSVGRGBColor(in long red, in long green, in long blue) raises(SVGException); void moveFocus(in unsigned short motionType) raises(DOMException); void setFocus(in DOMObject object) raises(DOMException); DOMObject getCurrentFocusedObject(); };
The position and size of the viewport (implicit or explicit) that corresponds to this 'svg' element. When the user agent is actually rendering the content, then the position and size values represent the actual values when rendering. If this SVG document is embedded as part of another document (e.g., via the HTML 'object' element), then the position and size are unitless values in the coordinate system of the parent document. (If the parent uses CSS or XSL layout, then unitless values represent pixel units for the current CSS or XSL viewport, as described in the CSS2 specification.) If the parent element does not have a coordinate system, then the user agent should provide reasonable default values for this attribute.
The object itself and its contents are both readonly. DOMException with error code NO_MODIFICATION_ALLOWED_ERR is raised if attempt is made to modify it. The returned SVGRect object is "live", i.e. its x, y, width, height is automatically updated if viewport size or position changes.
[ a c e ] [ b d f ] [ 0 0 1 ]
fill
, stroke
, and color
.
interface SVGRGBColor { readonly attribute unsigned long red; readonly attribute unsigned long green; readonly attribute unsigned long blue; };
interface SVGRect { attribute float x; attribute float y; attribute float width; attribute float height; };
interface SVGPoint { attribute float x; attribute float y; };
The native implementations must support the following simplifications or canonicalization of path segments. Any simplifications should be lossless.
interface SVGPath { const unsigned short MOVE_TO = 77; const unsigned short LINE_TO = 76; const unsigned short CURVE_TO = 67; const unsigned short QUAD_TO = 81; const unsigned short CLOSE = 90; readonly attribute unsigned long numberOfSegments; unsigned short getSegment(in unsigned long cmdIndex) raises(DOMException); float getSegmentParam(in unsigned long cmdIndex, in unsigned long paramIndex) raises(DOMException); void moveTo(in float x, in float y); void lineTo(in float x, in float y); void quadTo(in float x1, in float y1, in float x2, in float y2); void curveTo(in float x1, in float y1, in float x2, in float y2, in float x3, in float y3); void close(); };
This matrix transforms source coordinates (x, y) into destination coordinates (x', y') by considering them to be a column vector and multiplying the coordinate vector by the matrix according to the following process:
[ x' ] [ a c e ] [ x ] [ a.x + c.y + e ] [ y' ] = [ b d f ] [ y ] = [ b.x + d.y + f ] [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
interface SVGMatrix { float getComponent(in unsigned long index) raises(DOMException); SVGMatrix mMultiply(in SVGMatrix secondMatrix); SVGMatrix inverse() raises(SVGException); SVGMatrix mTranslate(in float x, in float y); SVGMatrix mScale(in float scaleFactor); SVGMatrix mRotate(in float angle); };
getComponent(0)
is a, getComponent(1)
is b, etc.
index
is invalid.multiply(T)
, where T
is an
SVGMatrix
object represented by the following
matrix:
[ 1 0 x ] [ 0 1 y ] [ 0 0 1 ]
multiply(S)
, where S
is an SVGMatrix
object represented by the following matrix:
[ scaleFactor 0 0 ] [ 0 scaleFactor 0 ] [ 0 0 1 ]
multiply(R)
, where R
is an
SVGMatrix
object represented by the following matrix:
[ cos(angle) -sin(angle) 0 ] [ sin(angle) cos(angle) 0 ] [ 0 0 1 ]
<g id="group1" transform="translate(10, 20)" fill="red">
<rect id="rect1" transform="scale(2)" x="10" y="10" width="50" height="50"/>
<rect id="rect2" x="10" y="10" width="100" height="100"/>
<g id="group2" transform="translate(10, 20)">
<rect id="rect3" x="0" y="10" width="150" height="50"/>
<circle id="circle1" cx="20" cy="20" r="100" />
</g>
</g>
Result:
[group1] : {-70.0, -60.0, 230.0, 200.0}
[rect1] : {10.0, 10.0, 50.0, 50.0}
[rect2] : {10.0, 10.0, 100.0, 100.0}
[group2] : {-80.0, -80.0, 230.0, 200.0}
[rect3] : {0.0, 10.0, 150.0, 50.0}
[circle1] : {-80.0, -80.0, 200.0, 200.0}
<g id="group1" transform="translate(10, 20)" fill="red">
<rect id="rect2" x="10" y="10" width="400" height="0"/>
<g id="group2" transform="translate(10, 20)">
<rect id="rect3" x="0" y="10" width="150" height="50"/>
</g>
</g>
Result:
[group1] : {10.0, 10.0, 400.0, 70.0}
[rect2] : {10.0, 10.0, 400.0, 0.0}
[group2] : {0.0, 10.0, 150.0, 50.0}
[rect3] : {0.0, 10.0, 150.0, 50.0}
<svg id="mySVG" width="10" height="20">
<g id="group1" transform="translate(10, 20)" fill="red">
<rect id="rect1" x="10" y="10" width="100" height="100"/>
<ellipse id="ellipse1" cx="20" cy="20" rx="0" ry="70" />
</g>
</svg>
Result:
[mySVG] : {20.0, -30.0, 100.0, 160.0}
[group1] : {10.0, -50.0, 100.0, 160.0}
[rect1] : {10.0, 10.0, 100.0, 100.0}
[ellipse1] : {20.0, -50.0, 0.0, 140.0}
<svg id="mySVG" width="0" height="50">
<g id="group1" transform="translate(10, 20)" fill="red" >
<rect id="rect1" x="10" y="10" width="50" height="50"/>
<g id="group2" transform="translate(10, 20)">
<rect id="rect2" x="0" y="10" width="150" height="0"/>
<circle id="circle1" cx="20" cy="20" r="500"/>
</g>
</g>
</svg>
Result:
[mySVG] : {-460.0, -440.0, 1000.0, 1000.0}
[group1] : {-470.0, -460.0, 1000.0, 1000.0}
[rect1] : {10.0, 10.0, 50.0, 50.0}
[group2] : {-480.0, -480.0, 1000.0, 1000.0}
[rect2] : {0.0, 10.0, 150.0, 0.0}
[circle1] : {-480.0, -480.0, 1000.0, 1000.0}
<svg>
<defs>
<rect id="myRect" x="0" y="0" width="60" height="40"/>
</defs>
<use id="myUse" xlink:href="#myRect" x="-30" y="-20"/>
</svg>
Result:
[myRect] : {0.0, 0.0, 60.0, 40.0}
[myUse] : {-30.0, -20.0, 60.0, 40.0}
<g id="emptyG"/>
Result:
[emptyG] : {null}
<g id="g1">
<g id="g1.1.display.none" display="none">
<rect id="rect1" x="10" y="10" width="40" height="40"/>
<g/>
<rect id="rect2.visibility.hidden" visibility="hidden" x="30" y="60" width="10" height="20"/>
</g>
Result:
[g1] : {30.0, 60.0, 10.0, 20.0}
[g1.1.display.none] : {10.0, 10.0, 40.0, 40.0}
[rect1] : {10.0, 10.0, 40.0, 40.0}
[rec2.visibility.hidden] : {30.0, 60.0, 10.0, 20.0}
<g id="g1">
<line id="line1" x2="100" y2="100" transform="rotate(-45)"/>
</g>
Result:
[g1] : {0.0, 0.0, 141.42136, 0}
[line1] : {0.0, 0.0, 100.0, 100.0}
<g>
<line id="thickLine" stroke-width="10" x2="100" y2="0"/>
</g>
Result:
[thickLine] : {0.0, 0.0, 100.0, 0.0}
<svg id="rootSvg" width="500" height="300" viewBox="0 0 200 100">
<rect x="-100" y="-200" width="500" height="100"/>
</svg>
Result:
[rootSVG] : {-100, -200, 500, 100}
interface SVGLocatable { SVGRect getBBox(); SVGMatrix getScreenCTM(); SVGRect getScreenBBox(); };
Returns the tight bounding box in current user coordinate space (i.e., after application of the transform attribute or the viewbox). Tight bounding box is the smallest possible rectangle that includes the geometry of all contained graphics elements excluding stroke. The calculation is done in the user coordinate space of the element. When bounding box is calculated elements with display property (trait) set to none are ignored. Exact rules for the bounding box calculation are given in the SVG spec.
null
is returned if this element is not hooked into the
document tree.
null
is returned if this element is not hooked into the
document tree.
interface SVGLocatableElement : SVGElement, SVGLocatable { };
Trait manipulation interface. This interface is implemented by all svg elements. Each trait corresponds to an attribute which is parsed and understood by the element and in most cases animatable. Unlike attributes, each element has a well-defined set of traits and attempting to access an undefined trait is an error. Also unlike attributes traits can be typed. When getting and setting trait values, accessor of the correct type must be used or an exception will be thrown.
Initial trait values come from parsing corresponding attributes. In the environments where styling is supported, trait values also come from the stylesheets or styling attributes. If value is not specified, but corresponding attribute (or property for environments where styling is supported) is inherited, inherited value is returned as a result of the trait query method. If it is not inherited, default value is returned. The value which is returned is always a base value, before SMIL animation is applied.
The different getPresentationTrait methods return either the current animated value if the given trait is currently being animated (per the SMIL specification) or the base value if the given trait is not currently being animated.
Note about invalid/unsupported trait values: There are two situations where the various trait setter methods(such as setTrait, setFloatTrait or setPathTrait methods) consider a value invalid and throw a DOMException with the INVALID_ACCESS_ERR code. The trait methods will consider the value to be invalid if its 'in error' [link to definitions section 1.5].
The second situation is when the trait value is invalid with regards to animations currently applied to the trait. The value is considered invalid because it would put the animation, and therefore the document, in an error state. For example, if a <path> element has animations on its "d" attribute, trying to change the "d" attribute to a value incompatible with the animations will cause the exception to happen.
The trait setter methods will consider a value unsupported when it complies with the definition for an unsupported value [link to definitions section 1.5]. This will result in a DOMException thrown with the NOT_SUPPORTED_ERR code. For example, trying to set the "stroke-linejoin" trait to "foo" would cause this exception.
interface TraitAccess { DOMString getTrait(in DOMString name) raises(DOMException); DOMString getTraitNS(in DOMString namespaceURI, in DOMString name) raises(DOMException); float getFloatTrait(in DOMString name) raises(DOMException); SVGMatrix getMatrixTrait(in DOMString name) raises(DOMException); SVGRect getRectTrait(in DOMString name) raises(DOMException); SVGPath getPathTrait(in DOMString name) raises(DOMException); SVGRGBColor getRGBColorTrait(in DOMString name) raises(DOMException); DOMString getPresentationTrait(in DOMString name) raises(DOMException); DOMString getPresentationTraitNS(in DOMString namespaceURI, in DOMString name) raises(DOMException); float getFloatPresentationTrait(in DOMString name) raises(DOMException); SVGMatrix getMatrixPresentationTrait(in DOMString name) raises(DOMException); SVGRect getRectPresentationTrait(in DOMString name) raises(DOMException); SVGPath getPathPresentationTrait(in DOMString name) raises(DOMException); SVGRGBColor getRGBColorPresentationTrait(in DOMString name) raises(DOMException); void setTrait(in DOMString name, in DOMString value) raises(DOMException); void setTraitNS(in DOMString namespaceURI, in DOMString name, in DOMString value) raises(DOMException); void setFloatTrait(in DOMString name, in float value) raises(DOMException); void setMatrixTrait(in DOMString name, in SVGMatrix matrix) raises(DOMException); void setRectTrait(in DOMString name, in SVGRect rect) raises(DOMException); void setPathTrait(in DOMString name, in SVGPath path) raises(DOMException); void setRGBColorTrait(in DOMString name, in SVGRGBColor color) raises(DOMException); };
interface ElementTraversal { readonly attribute Element firstElementChild; readonly attribute Element lastElementChild; readonly attribute Element nextElementSibling; readonly attribute Element previousElementSibling; };
null
if this element has no child elements.
null
if this element has no element sibling
nodes that come after this one in the document tree.
This interface can also be used read and manipulate the value of "traits" associated with this SVGElement. Each trait corresponds to an attribute or property,which is parsed and understood by the element and in most cases animatable. Unlike attributes, each element has a well-defined set of traits and attempting to access undefined trait is an error. Also unlike attributes traits are typed and their values are normalized; for instance SVG path specification is parsed and all path commands are converted to their absolute variants, it is not possible to say through the value of the trait if a path command was absolute or relative. When getting and setting trait values, accessor of the correct type must be used or exception will be thrown.
Initial trait values come from parsing corresponding attributes. If value is not specified, but corresponding attribute (or property for environments where styling is supported) is inherited, inherited value is returned as a result of the trait query method. If it is not inherited, default value is returned. Default values are also returned in the case when there is no parent to inherit from, for ex: when you create a new element, set a trait value to 'inherit', but there is no parent for inheritance. It is important to note that the value which is returned is always a base value (i.e. before animation is applied), and this is true for both static and animated content.
Setting a trait value has the same effect as changing a corresponding attribute, but trait setters can operate on typed values. The value which is modified is always a base value. For inheritable traits the trait value can always be set to "inherit" (but querying the value will always return the actual inherited value as explained above).
The table below shows the list of attributes and properties that SVG Tiny DOM 1.2 implementations must support. Each attribute row lists the allowed getter and setter (s). The 3:rd column specifies the default values that must be used for each attribute or property. Unless explicitly stated in the 'Comments' column, a supported attribute is accessible on all elements it can belong to. See the attribute section for a list of attributes and which elements they belong to.
For 'REQUIRED' attributes, there are two cases:
Note: For some of the attributes and data types additional rules apply. These rules are defined below the table.
Attribute | Trait Getter | Trait Setter | Default Values | Comments |
accumulate | getTrait [none | sum] | setTrait [none | sum] | none | |
additive | getTrait [replace | sum] | setTrait [replace | sum] | replace | |
attributeName | getTrait | setTrait | ||
audio-level | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] | 1.0f | |
baseProfile | getTrait | Not available (readonly) | "tiny" | |
begin | N/A | setTrait | ||
calcMode | getTrait [discrete | linear | paced | spline] | setTrait [discrete | linear | paced | spline] | linear (except for animateMotion) paced (for animateMotion) |
|
color | getRGBColorTrait [SVGRGBColor] getTrait [SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait [inherit | SVGRGBColor] |
rgb(0,0,0) | -See RGB access rule. |
cx | getFloatTrait | setFloatTrait | 0.0f | |
cy | getFloatTrait | setFloatTrait | 0.0f | |
d | getPathTrait [SVGPath] | setPathTrait [SVGPath] | REQUIRED(Empty SVGPath) | |
display | getTrait [inline | none ] | setTrait [inline | none | inherit ] | "inline" | |
dur | N/A | setTrait | ||
editable | getTrait [true | false] | setTrait [true | false] | "false" | |
fill | getRGBColorTrait [SVGRGBColor] getTrait [none | <Paint Server> | SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait [none | currentColor | <Paint Server> | inherit | SVGRGBColor] |
rgb(0,0,0) | -See RGB access rule. -Attribute defining the fill-color. |
fill | getTrait[freeze | remove] | setTrait[freeze | remove] | "remove" | -Attribute defining the fill behavior of a smil animation element. |
fill-opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] setTrait[inherit] |
1.0f | |
fill-rule | getTrait [nonzero | evenodd] | setTrait [nonzero | evenodd | inherit] | "nonzero" | |
focusable | getTrait [true | false] | setTrait [true | false | auto] | ||
focusNorth | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusNorthEast | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusEast | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusSouthEast | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusSouth | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusSouthWest | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusWest | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusNorthWest | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusNext | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusPrev | getTrait [null | IDREF] | setTrait [IDREF | auto] | ||
focusable | getTrait [true | false] | setTrait [true | false | auto] | ||
font-family | getTrait [single, computed font-family value] | setTrait [same syntax as font-family attribute] | User-Agent | |
font-size | getFloatTrait [value >= 0] | setFloatTrait [value >= 0] setTrait [inherit] |
User-Agent | |
font-style | getTrait [normal | italic | oblique ] | setTrait [normal | italic | oblique | inherit] | "normal" | |
font-weight | getTrait [100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 ] | setTrait [normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit] | "normal" | |
gradientUnits | getTrait [userSpaceOnUse | objectBoundingBox] | setTrait [userSpaceOnUse | objectBoundingBox] | "objectBoundingBox" | |
height | getFloatTrait [value >= 0] | setFloatTrait [value >= 0] | REQUIRED(0.0f) | |
id | getTrait | setTrait | ||
keyPoints | N/A | setTrait | ||
keySplines | N/A | setTrait | ||
keyTimes | N/A | setTrait | ||
max | N/A | setTrait | ||
min | N/A | setTrait | ||
offset | getFloatTrait[value >= 0 && value <= 1] | setFloatTrait[value >= 0 && value <= 1] | ||
opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] setTrait[inherit] |
||
path | getPathTrait [SVGPath] | setPathTrait [SVGPath] | REQUIRED(Empty SVGPath) | |
r | getFloatTrait [ value >= 0] | setFloatTrait [value >= 0] | REQUIRED (0.0f) | |
repeatCount | N/A | setTrait | ||
repeatDur | N/A | setTrait | ||
restart | getTrait [always | whenNotActive | never] | setTrait [always | whenNotActive | never] | always | |
rx | getFloatTrait [value >= 0] | setFloatTrait [value >= 0] | 0.0f | |
ry | getFloatTrait [value >= 0] | setFloatTrait [value >= 0] | 0.0f | |
snapShotTime | getFloatTrait [value >= 0] | setFloatTrait [value >= 0] | 0.0f | |
solid-color | getRGBColorTrait [SVGRGBColor] getTrait [SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait [SVGRGBColor | inherit] |
rgb(0,0,0) | -See RGB access rule. |
solid-opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] | 1.0f | |
stop-color | getRGBColorTrait [SVGRGBColor] getTrait [none | <Paint Server> | SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait(none | currentColor | <Paint Server> | inherit | SVGRGBColor] |
rgb(0,0,0) | -See RGB access rule. |
stop-opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] setTrait[inherit] |
1.0f | |
stroke | getRGBColorTrait [SVGRGBColor] getTrait [none | <Paint Server> | SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait [none | currentColor | <Paint Server> | inherit | SVGRGBColor] |
"none" | -See RGB access rule. |
stroke-dashoffset | getFloatTrait | setTrait [inherit] setFloatTrait |
0.0f | |
stroke-linecap | getTrait [butt | round | square] | setTrait [butt | round | square | inherit] | "butt" | |
stroke-linejoin | getTrait [miter | round | bevel ] | setTrait [miter | round | bevel | inherit] | "miter" | |
stroke-miterlimit | getFloatTrait [ value >= 1] | setTrait [inherit] setFloatTrait [value >= 1] |
4.0f | |
stroke-opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] setTrait[inherit] |
1.0f | |
stroke-width | getFloatTrait [value >= 0] | setTrait [inherit] setFloatTrait [value >= 0] |
1.0f | |
target | getTrait | setTrait | "" | |
"text" | getTrait("#text") ["text content"] | setTrait("#text", "text content") | -See Text Node Access for details. | |
text-anchor | getTrait [start | middle | end] | setTrait [start | middle | end | inherit ] | "start" | |
transform | getMatrixTrait [SVGMatrix] getTrait |
setMatrixTrait [SVGMatrix] setTrait |
Identity matrix (1,0,0,1,0,0) | -See Transform access rule. |
type | For animateTransform: getTrait [translate | scale | rotate | skewX | skewY] | For animateTransform: setTrait [translate | scale | rotate | skewX | skewY] | ||
values | N/A | setTrait | ||
vector-effect | getTrait [default|non-scaling-stroke] | setTrait [default|non-scaling-stroke] | "default" | |
version | getTrait | Not available (readonly) | "1.2" | |
viewBox | getRectTrait [null, SVGRect] | setRectTrait [SVGRect] setTrait [none] |
null | If the actual trait value is not an SVGRect (i.e. "none"), the getRectTrait method will return null. |
viewport-fill | getRGBColorTrait [SVGRGBColor] getTrait [none | <Paint Server> | SVGRGBColor] |
setRGBColorTrait [SVGRGBColor] setTrait [none | currentColor | <Paint Server> | SVGRGBColor] |
"none" | -See RGB access rule. |
viewport-fill-opacity | getFloatTrait [value >= 0 && value <= 1] | setFloatTrait [value >= 0 && value <= 1] | 1.0f | |
visibility | getTrait [visible | hidden] | setTrait [visible | hidden | inherit] | "visible" | |
width | getFloatTrait [ value >= 0] | setFloatTrait [ value >= 0] | REQUIRED (0.0f) | |
x | getFloatTrait (array of x-values not supported) |
setFloatTrait (array of x-values not supported) |
0.0f | |
x1 | getFloatTrait | setFloatTrait | 0.0f | |
x2 | getFloatTrait | setFloatTrait | 0.0f | |
xlink:href | getTrait [absolute URI] | setTrait | "" | |
y | getFloatTrait (array of y-values not supported) |
setFloatTrait (array of y-values not supported) |
0.0f | |
y1 | getFloatTrait | setFloatTrait | 0.0f | |
y2 | getFloatTrait | setFloatTrait | 0.0f | |
zoomAndPan | getTrait [disable | magnify] | setTrait [disable | magnify] | "magnify" |
Accessing rules for RGBColorTrait
The getRGBColorTrait is used to get the RGB color. If the actual trait value is not an RGBColor, i.e. "none" or a link to a paint server (e.g. to a gradient or a solid-color), this method will raise a DOMException with error code TYPE_MISMATCH_ERR and getTrait should be used instead. setTrait must be used to set a color type that is not an RGBColor.
Accessing rules for 'transform' attribute
The transform attribute in SVGT1.2 can have two types of values. The 'normal' transformation list (e.g. scale, translate, rotate, matrix etc) or the newly introduced ref(svg) type. getMatrixTrait returns the current evaluated matrix in both cases. If the user needs to know that the transform attribute value was a 'ref' he must call getTrait. By using setTrait he can set the transform attribute to ref(svg).
Accessing rules for animation and font related elements
The following rule applies to Smil-animation elements (<animate>, <animateTransform>, <animateColor>, <animateMotion>, <set>) and font element with its children (<font>, <font-face, <missing-glyph>, <glyph>, <hkern>, <font-face-src>, <font-face-uri>, <font-face-name>).
These elements can be inserted and removed from the tree but they cannot be modified once inserted into the tree. Manipulating animations while they are in the DOM tree and possiblely active would result in undefined behaviour. This may also have an effect on past resolved times. This restriction means that if the author wishes to add animations via script, the element must be modified when it is not attached to the tree. A similar reasoning applies to the different font elements, modifying them while attached to the tree might lead to unpredictable result. Following is an example of adding animation to the tree including setting the properties prior to insertion.
<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" id="svg-root"
width="100%" height="100%" viewBox="0 0 480 360">
<rect id="myRect" fill="green" x="10" y="10" width="200" height="100" stroke="black" stroke-width="2"/>
</svg>
SVGElement newAnimate = (SVGElement)document.createElementNS(svgNS, "animate");
newAnimate.setTrait("attributeName", "fill");
newAnimate.setTrait("from", "red");
newAnimate.setTrait("to", "blue");
newAnimate.setTrait("dur", "5");
newAnimate.setTrait("repeatCount", "10");
Element myRect = document.getElementById("myRect");
myRect.appendChild(newAnimate);
interface SVGElement : dom::Element, events::EventTarget, TraitAccess, ElementTraversal { attribute DOMString id; };
interface SVGAnimationElement : SVGElement, smil::ElementTimeControl { };
interface SVGVisualMediaElement : SVGLocatableElement, SVGAnimationElement { };
Example #1: The usage of java together with the 'script' element
The example rely on the fact the 'myclasses.jar' jar file
contains a MANIFEST file with the following entry:
SVG-Handler-Class: org.sample.SVGHandler
<svg xmlns:svg="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500">
<script type="application/java-archive" xlink:href="myclasses.jar"/>
<rect id="therect" x="0" y="0" width="100" height="100"/>
</svg>
package org.sample.SVGHandler
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
public class SVGHandler implements EventListenerInitializer2 {
public void initializeEventListeners(Element scriptElement) {
Document document = scriptElement.ownerDocument;
Element rec = document.getElementById("therect");
rec.addEventListener("click", new MyListener(), true);
}
public EventListener createEventListener(Element handlerElement) {}
}
An instance of "MyListener" listener will be called when a 'click' event will occur on the rect element.
Example #2: The usage of java together with the 'handler' element
The example rely on the fact the 'myclasses.jar' jar file
contains a MANIFEST file with the following entry:
SVG-Handler-Class: org.sample.SVGHandler
<svg xmlns:svg="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500">
xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:myns="http://sample.org/myNS">
<script id="init" type="application/java-archive" xlink:href="myclasses.jar"/>
<rect id="therect" x="0" y="0" width="100" height="100">
<handler type="application/java" ev:event="click"
xlink:href="#init" myns:listenerClass="MyListener">
</rect>
</svg>
package org.sample.SVGHandler
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
public class SVGHandler implements EventListenerInitializer2 {
public void initializeEventListeners(Element scriptElement) {}
public EventListener createEventListener(Element handlerElement) {
EventListener listenerInstance = null;
try {
String listenerClass = ((TraitAccess)handlerElement).
getTraitNS("http://sample.org/myNS", "listenerClass");
listenerInstance = Class.forName(listenerClass).newInstance();
} catch (Exception e) {}
return listenerInstance;
}
}
An instance of "MyListener" listener will be called when a 'click' event will occur on the rect element. What createEventListener does is totally in the hand of the Java developer, the listener instance can be hardcoded or fully configured from information put on the handler element as shown here.
interface EventListenerInitializer2 { void initializeEventListeners( in dom::Element scriptElement ); events::EventListener createEventListener( in dom::Element handlerElement ); };
The majority of scripted SVG documents in existence make use of the browser specific Window interface. SVG 1.2 specifies an SVGGlobal interface, taking into account the de-facto standard that already exists, as well as adding the new features present in SVG 1.2. SVGGlobal inherits from the Global interface, which is currently defined to be empty. The Global interface is designed to be the parent interface for language specific window objects. In scripting implementations, the methods and attributes defined by the Global object are normally part of the global execution context.
Interface SVGGlobal provides a global object for scripts embedded in a SVG document.
interface SVGGlobal : global::Global { global::Connection createConnection(); void gotoLocation(in DOMString newURI); readonly attribute Document document; readonly attribute global::Global parent; };