// hmi_tree.ysl2
// Location identifies uniquely SVGHMI instance
param "instance_name";
// HMI Tree computed from VARIABLES.CSV in svghmi.py
const "hmitree", "ns:GetHMITree()";
const "_categories" {
noindex > HMI_PLC_STATUS
noindex > HMI_CURRENT_PAGE
}
const "categories", "exsl:node-set($_categories)";
// HMI Tree Index
const "_indexed_hmitree" apply "$hmitree", mode="index";
const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";
emit "preamble:hmi-tree" {
| var hmi_hash = [«$hmitree/@hash»];
|
| var heartbeat_index = «$indexed_hmitree/*[@hmipath = '/HEARTBEAT']/@index»;
|
| var current_page_var_index = «$indexed_hmitree/*[@hmipath = concat('/CURRENT_PAGE_', $instance_name)]/@index»;
|
| var hmitree_types = [
foreach "$indexed_hmitree/*"
| "«substring(local-name(), 5)»"`if "position()!=last()" > ,`
| ];
|
| var hmitree_paths = [
foreach "$indexed_hmitree/*"
| "«@hmipath»"`if "position()!=last()" > ,`
| ];
|
| var hmitree_nodes = {
foreach "$indexed_hmitree/*[local-name() = 'HMI_NODE']"
| "«@hmipath»" : [«@index», "«@class»"]`if "position()!=last()" > ,`
| };
|
}
template "*", mode="index" {
param "index", "0";
param "parentpath", "''";
const "content" {
const "path"
choose {
when "count(ancestor::*)=0" > /
when "count(ancestor::*)=1" > /«@name»
otherwise > «$parentpath»/«@name»
}
choose {
when "not(local-name() = $categories/noindex)" {
xsl:copy {
attrib "index" > «$index»
attrib "hmipath" > «$path»
foreach "@*" xsl:copy;
}
apply "*[1]", mode="index"{
with "index", "$index + 1";
with "parentpath" > «$path»
}
}
otherwise {
apply "*[1]", mode="index"{
with "index", "$index";
with "parentpath" > «$path»
}
}
}
}
copy "$content";
apply "following-sibling::*[1]", mode="index" {
with "index", "$index + count(exsl:node-set($content)/*)";
with "parentpath" > «$parentpath»
}
}
include parse_labels.ysl2
const "_parsed_widgets" {
widget type="VarInitPersistent" {
arg value="0";
path value="lang";
}
apply "$hmi_elements", mode="parselabel";
}
const "parsed_widgets","exsl:node-set($_parsed_widgets)";
def "func:widget" {
param "id";
result "$parsed_widgets/widget[@id = $id]";
}
def "func:is_descendant_path" {
param "descend";
param "ancest";
// TODO : use HMI tree to answer more accurately
result "string-length($ancest) > 0 and starts-with($descend,$ancest)";
}
def "func:same_class_paths" {
param "a";
param "b";
const "class_a", "$indexed_hmitree/*[@hmipath = $a]/@class";
const "class_b", "$indexed_hmitree/*[@hmipath = $b]/@class";
result "$class_a and $class_b and $class_a = $class_b";
}
// Debug data
template "*", mode="testtree"{
param "indent", "''";
> «$indent» «local-name()»
foreach "@*" > «local-name()»="«.»"
> \n
apply "*", mode="testtree" {
with "indent" value "concat($indent,'>')"
};
}
emit "debug:hmi-tree" {
| Raw HMI tree
apply "$hmitree", mode="testtree";
|
| Indexed HMI tree
apply "$indexed_hmitree", mode="testtree";
|
| Parsed Widgets
copy "_parsed_widgets";
apply "$parsed_widgets", mode="testtree";
}