SVGHMI: Exclude non-widget HMI:* labeled elements from hmi_widget. Namely : HMI:Page HMI:Lang and HMI:List have been excluded.
// inline_svg.ysl2
//
// Produce Inline SVG element of resulting XHTML page.
// Since stylesheet output namespace is xhtml, templates that output svg have to be explicitely declared as such
in xsl decl svgtmpl(match, xmlns="http://www.w3.org/2000/svg") alias template;
in xsl decl svgfunc(name, xmlns="http://www.w3.org/2000/svg") alias template;
// Identity template :
// - copy every attributes
// - copy every sub-elements
template "@* | node()", mode="inline_svg" {
// use real xsl:copy instead copy-of alias from yslt.yml2
if "not(@id = $discardable_elements/@id)"
xsl:copy apply "@* | node()", mode="inline_svg";
}
// replaces inkscape's height and width hints. forces fit
template "svg:svg/@width", mode="inline_svg";
template "svg:svg/@height", mode="inline_svg";
svgtmpl "svg:svg", mode="inline_svg" svg {
attrib "preserveAspectRatio" > none
attrib "height" > 100vh
attrib "width" > 100vw
apply "@* | node()", mode="inline_svg";
}
// ensure that coordinate in CSV file generated by inkscape are in default reference frame
template "svg:svg[@viewBox!=concat('0 0 ', @width, ' ', @height)]", mode="inline_svg" {
error > ViewBox settings other than X=0, Y=0 and Scale=1 are not supported
}
// ensure that coordinate in CSV file generated by inkscape match svg default unit
template "sodipodi:namedview[@units!='px' or @inkscape:document-units!='px']", mode="inline_svg" {
error > All units must be set to "px" in Inkscape's document properties
}
////// Clone unlinking
//
// svg:use (inkscape's clones) inside a widgets are
// replaced by real elements they refer in order to :
// - allow finding "needle" element in "meter" widget,
// even if "needle" is in a group refered by a svg use.
// - if "needle" is visible through a svg:use for
// each instance of the widget, then needle would show
// the same position in all instances
//
// For now, clone unlinkink applies to descendants of all widget except HMI:Page
// TODO: narrow application of clone unlinking to active elements,
// while keeping static decoration cloned
const "to_unlink", "$hmi_elements[not(@id = $hmi_pages)]//svg:use";
svgtmpl "svg:use", mode="inline_svg"
{
choose {
when "@id = $to_unlink/@id"
call "unlink_clone";
otherwise
xsl:copy apply "@* | node()", mode="inline_svg";
}
}
// to unlink a clone, an group containing a copy of target element is created
// that way, style and transforms can be preserved
const "_excluded_use_attrs" {
name > href
name > width
name > height
name > x
name > y
}
const "excluded_use_attrs","exsl:node-set($_excluded_use_attrs)";
svgfunc "unlink_clone"{
g{
// include non excluded attributes
foreach "@*[not(local-name() = $excluded_use_attrs/name)]"
attrib "{name()}" > «.»
const "targetid","substring-after(@xlink:href,'#')";
apply "//svg:*[@id = $targetid]", mode="unlink_clone"{
with "seed","@id";
}
}
}
// clone unlinking is really similar to deep-copy
// all nodes are sytematically copied
svgtmpl "@id", mode="unlink_clone" {
param "seed";
attrib "id" > «$seed»_«.»
}
svgtmpl "@*", mode="unlink_clone" xsl:copy;
// copying widgets would have unwanted effect
// instead widget is refered through a svg:use.
svgtmpl "svg:*", mode="unlink_clone" {
param "seed";
choose {
// node recursive copy ends when finding a widget
when "@id = $hmi_elements/@id" {
// place a clone instead of copying
use{
attrib "xlink:href" > «concat('#',@id)»
}
}
otherwise {
xsl:copy apply "@* | node()", mode="unlink_clone" {
with "seed","$seed";
}
}
}
}
const "result_svg" apply "/", mode="inline_svg";
const "result_svg_ns", "exsl:node-set($result_svg)";
emit "preamble:inline-svg" {
| let id = document.getElementById.bind(document);
| var svg_root = id("«$svg/@id»");
}
emit "debug:clone-unlinking" {
|
| Unlinked :
foreach "$to_unlink"{
| «@id»
}
}