The dSVG expression syntax was created to allow the attribute values of dSVG elements to be dynamic. With dSVG expressions, attribute values can be dependent on the real-time values of other attributes in the DOM. This syntax was intended to be simpler to use than XPath and ECMAScript, and to provide a subset of their most commonly used features.
dSVG expressions are denoted by the %% characters. Whatever is contained with the % characters gets evaluated. The basic unit of reference is elementID@attributeName. For example, %myRectangle@width% would be resolved to the numeric value of the width attribute of the element //.[ @id = "myRectangle"] (as denoted with the XPath expression). This syntax is therefore intended to be used in documents where elements have unique ID's. Note that the attributeName can have a namespace prefix for any namespace declared in the document.
elementID@attributeName | elementID@nameSpace:attributeName
Some dSVG behaviors, like 'loadXML', can create document fragments. These are named at the time of creation and can be referred to within %% expressions like so:
docID.elementID@nameSpace:attributeName
elementID@bbox.x : returns the x-coordinate of the element's bounding box
(i.e. the left)
elementID@bbox.y : returns the y-coordinate of the element's bounding box (i.e.
the top)
elementID@bbox.width : returns the width of the element's bounding box
elementID@bbox.height : returns the height of the element's bounding box
elementID@cdata : returns the text content of the element
@event.type: returns the type of event that triggered the behavior (e.g.
'mouseover', 'SVGResize', 'keypress', etc.)
@event.targetNodeName: returns the nodeName of the element that was the target
of the event that triggered the behavior
@event.targetID: returns the 'id' attribute of the element that was the target
of the event that triggered the behavior
@event.currentTargetNodeName: returns the nodeName of the element that observed
the event that triggered the behavior
@event.currentTargetID: returns the 'id' attribute of the element that observed
the event that triggered the behavior
@event.shiftKey: returns 'true' if the Shift-key is pressed, 'false' otherwise.
@event.ctrlKey: returns 'true' if the Ctrl-key is pressed, 'false' otherwise.
@event.keyCode: returns the keyCode attribute of the 'keydown' or 'keyup' event
that triggered the behavior.
@event.keyID: returns the key identifier--a string representation of
the keyCode attribute of the 'keydown' or 'keyup' event that triggered the
behavior (e.g. 'Space', 'Enter', 'a').
@event.charCode: returns the charCode attribute of the 'keypress' event that
triggered the behavior.
@event.char: returns the string representation of the charCode attribute of the
'keypress' event that triggered the behavior (e.g. 'A' or 'a').
Note: The real event object has 'target' and 'currentTarget' attributes, which are node objects. Since these would only be useful in a scripting environment, dSVG instead offers the "virtual" event attributes 'targetNodeName', 'targetID', 'currentTargetNodeName' and 'currentTargetID'.
A keyCode event attribute is automatically generated in response to the 'keydown' and 'keyup' events. For ease of authoring, dSVG offers a "virtual" event attribute called 'keyID', which is a string identifier for the various keys. These keyID's resemble, as closely as possible, the key identifiers listed in the W3C Working Draft of the DOM Level 3 Events Specification (http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/keyset.html). The mapping between the keyCodes and their corresponding keyID's are listed below.
keyCode | keyID | keyCode | keyID | keyCode | keyID | keyCode | keyID | keyCode | keyID | ||||
8 | Backspace | 48 | 0 | 75 | K | 97 | NumPad1 | 118 | F7 | ||||
9 | Tab | 49 | 1 | 76 | L | 98 | NumPad2 | 119 | F8 | ||||
12 | Center | 50 | 2 | 77 | M | 99 | NumPad3 | 120 | F9 | ||||
13 | Enter | 51 | 3 | 78 | N | 100 | NumPad4 | 121 | F10 | ||||
16 | Shift | 52 | 4 | 79 | O | 101 | NumPad5 | 122 | F11 | ||||
17 | Control | 53 | 5 | 80 | P | 102 | NumPad6 | 123 | F12 | ||||
19 | Pause | 54 | 6 | 81 | Q | 103 | NumPad7 | 127 | Delete | ||||
20 | CapsLock | 55 | 7 | 82 | R | 104 | NumPad8 | 144 | NumLock | ||||
27 | Escape | 56 | 8 | 83 | S | 105 | NumPad9 | 146 | Scroll | ||||
32 | Space | 57 | 9 | 84 | T | 106 | Multiply | 186 | Semicolon | ||||
33 | PageUp | 65 | A | 85 | U | 107 | Add | 187 | Equals | ||||
34 | PageDown | 66 | B | 86 | V | 109 | Subtract | 188 | Comma | ||||
35 | End | 67 | C | 87 | W | 110 | Decimal | 189 | Hyphen | ||||
36 | Home | 68 | D | 88 | X | 111 | Divide | 190 | Period | ||||
37 | Left | 69 | E | 89 | Y | 112 | F1 | 191 | Slash | ||||
38 | Up | 70 | F | 90 | z | 113 | F2 | 192 | GraveAccent | ||||
39 | Right | 71 | G | 91 | WinLeft | 114 | F3 | 219 | LeftSquareBracket | ||||
40 | Down | 72 | H | 92 | WinRight | 115 | F4 | 220 | Blackslash | ||||
44 | PrintScreen | 73 | I | 93 | Apps | 116 | F5 | 221 | RightSquareBracket | ||||
45 | Insert | 74 | J | 96 | NumPad0 | 117 | F6 | 222 | Apostrophe |
Note: In some SVG viewers, the 'keyCode' event attribute for some keys may be inconsistent with the DOM Level 3 Events Specification, which is currently in the Working Draft phase.
An attribute consists of constant string data concatenated with evaluated expressions delimited by % symbols (a double %% acts as an escape). For example:
attribute="constant_one% expression_one %constant_two% expression_two %constant_three"
Each resolution expects an expression of the form:
% complex_expression %
where complex_expression can be of the form:
% simple_expression %
or:
% simple_expression ( complex_expression ) simple_expression %
Parentheses are resolved from innermost to outermost. Note that open parentheses require leading whitespace to distinguish them from functions.
simple_expression = [ string, Unit_Pattern, function, variable ] ( OpCode [ string, Unit_Pattern, function, variable ] )*
string = 'some string data' resolves to some string data
function = functionName( params ) : resolves to a function return value
The following ECMA math functions are available:
Other available functions are:
variable ( form: $variableName ) = % expression %
Variables refer to dSVG 'variable' elements and are intended as a convenient way of building and (re)using complex expressions, or simply for storage. It is the author's responsibility to not create self referential variables or circular variable references.
+ : addition
- : subtraction
* : multiplication
/ : division
, : list separator (ie. for parameters)
== : boolean equals
>= : boolean greater than or equal to
<= : boolean less than or equal to
!= : boolean not equal to
Expressions using opcodes resolve any Unit_Patterns, functions, variables and strings and then follow standard ecma expression rules.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg SYSTEM "../SVGdSVG.dtd"> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dsvg="http://www.corel.com/schemas/2002/dSVG" height="410px" width="744px" onload="init(evt)" viewBox="0 0 744 410"> <script type="text/ecmascript" xlink:href="dsvg/dSVG.js"/> <script type="text/ecmascript" xlink:href="dsvg/baseUI.js"/> <script type="text/ecmascript" xlink:href="dsvg/constraint.js"/> <script type="text/ecmascript" xlink:href="dsvg/focus.js"/> <script type="text/ecmascript" xlink:href="dsvg/setAttribute.js"/> <script type="text/ecmascript" xlink:href="dsvg/setStyle.js"/> <script type="text/ecmascript" xlink:href="dsvg/setTransform.js"/> <!-- template --> <rect height="40" width="744" y="0" x="0" fill="#5f86B1" id="title_rect"/> <text y="25" x="20" font-weight="bold" font-size="18" fill="white" id="text_1">dSVG sample behavior: focus - with added attributes focusGroup and focus</text> <text y="365" x="20" font-size="12" id="content">Content of file: dsvg:focus, dsvg:setTransform, dsvg:setAttribute, dsvg:setStyle, (added attributes dsvg:focus, dsvg:focusGroup)</text> <text y="380" x="20" font-size="12" id="expected">The dsvg:focusGroup attribute adds the ability to store the ID of similar type elements that are assigned to that group.</text> <text y="395" x="20" font-size="12" id="depend">Default focus can be given to an element (red circle above) by adding the dsvg:focus attribute to that element.</text> <line y2="340" x2="744" y1="340" x1="0" stroke-width="2" stroke="#5f86B1" fill="#5f86B1" id="bottom_line"/> <!-- adding behavior --> <text y="250" x="20" font-size="12" id="desc">The red, blue, green circles are part of the focusGroup. The orange circle is not.</text> <text y="150" x="200" font-size="12" id="desc_2">Click on the red, green and blue circles to set focus.</text> <text y="170" x="200" font-size="12" id="desc_3">Hover over the 'red', 'green' and 'blue' text elements to set focus.</text> <dsvg:focus elementID="redCircle" event="onclick" id="circleGroup"> <dsvg:setTransform scale="1.2" vAlign="middle" hAlign="middle" absolute="true" elementID="%circleGroup@elementID%"/> <dsvg:setTransform scale="1" vAlign="middle" hAlign="middle" absolute="true" elementID="%circleGroup@previousID%"/> <dsvg:setAttribute value="%(circleGroup@elementID)@fill%Text" attribute="elementID" elementID="textGroup"/> </dsvg:focus> <dsvg:focus event="onmouseover" id="textGroup"> <dsvg:setStyle value="%(textGroup@elementID)@cdata%" property="fill" elementID="%textGroup@elementID%"/> <dsvg:setStyle value="black" property="fill" elementID="%textGroup@previousID%"/> <dsvg:setAttribute value="%(textGroup@elementID)@cdata%Circle" attribute="elementID" elementID="circleGroup"/> </dsvg:focus> <circle dsvg:focus="true" dsvg:focusGroup="circleGroup" r="30" cy="100" cx="50" fill="red" id="redCircle"/> <circle dsvg:focusGroup="circleGroup" r="30" cy="200" cx="50" fill="blue" id="blueCircle"/> <circle dsvg:focusGroup="circleGroup" r="30" cy="100" cx="150" fill="green" id="greenCircle"/> <circle r="30" cy="200" cx="150" fill="orange" id="orangeCircle"/> <text dsvg:focus="true" dsvg:focusGroup="textGroup" y="80" x="200" id="redText">red</text> <text dsvg:focusGroup="textGroup" y="80" x="250" id="blueText">blue</text> <text dsvg:focusGroup="textGroup" y="80" x="300" id="greenText">green</text> <text y="80" x="350">orange</text> </svg>
Hovering the mouse over the 'text' element with id="blueText causes the behaviors within the second 'focus' element to be run. When the first 'setStyle' behavior is run, its 'value' attribute, which is equal to:
%(textGroup@elementID)@cdata%
resolves to:
%blueText@cdata%
which then further resolves to:
blue
<dsvg:button xlink:href="dsvg/skinButton_Windows.svg#skinButton" autoScale="true" disabled="false" selected="false" toggle="false" height="18" width="100" y="70" x="80" label="Evaluate" id="button1">
<dsvg:alert message="%button1@label == 'false' , 'is selected', 'is not selected') %"/>
</dsvg:button>
Pushing the button will run the 'alert' behavior. Its 'message' attribute, which is equal to:
message= "%button1@label + ' button ' + if(button1@selected == 'false' , 'is selected', 'is not selected')
which resolves to:
"button1@label + ' button ' + if( false , 'is selected', 'is not selected')
which further resolves to:
Evaluate button is selected