--- a/svghmi/detachable_pages.ysl2 Mon Mar 23 15:13:36 2020 +0100
+++ b/svghmi/detachable_pages.ysl2 Mon Mar 23 21:44:28 2020 +0100
@@ -91,13 +91,6 @@
const "_detachable_elements", "func:detachable_elements($hmi_pages)";
const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
-def "func:is_descendant_path" {
- result "string-length($ancest) > 0 and starts-with($descend,$ancest)";
const "forEach_widgets_ids", "$parsed_widgets/widget[@type = 'ForEach']/@id";
const "forEach_widgets", "$hmi_elements[@id = $forEach_widgets_ids]";
const "in_forEach_widget_ids", "func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id";
--- a/svghmi/gen_index_xhtml.xslt Mon Mar 23 15:13:36 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt Mon Mar 23 21:44:28 2020 +0100
@@ -74,49 +74,6 @@
- <func:function name="func:get_hmi_tree_elt">
- <xsl:param name="path"/>
- <xsl:param name="root" select="$hmitree"/>
- <xsl:text>get_hmi_tree_elt </xsl:text>
- <xsl:value-of select="$path"/>
- <xsl:if test="not(starts-with($path, '/'))">
- <xsl:message terminate="yes">
- <xsl:text>Given path "</xsl:text>
- <xsl:value-of select="$path"/>
- <xsl:text>" should start with a "/"</xsl:text>
- <xsl:variable name="stripped" select="substring($path, 2)"/>
- <xsl:variable name="token">
- <xsl:when test="contains($stripped, '/')">
- <xsl:value-of select="substring-before($stripped, '/')"/>
- <xsl:value-of select="$stripped"/>
- <xsl:when test="string-length($token) = 0">
- <func:result select="$root"/>
- <xsl:variable name="rest" select="substring-after($stripped, $token)"/>
- <xsl:variable name="match" select="$root/*[@name = $token]"/>
- <xsl:when test="string-length($rest) > 0">
- <func:result select="func:get_hmi_tree_el($rest, $match)"/>
- <func:result select="$match"/>
<xsl:template mode="parselabel" match="*">
<xsl:variable name="label" select="@inkscape:label"/>
<xsl:variable name="description" select="substring-after($label,'HMI:')"/>
@@ -185,6 +142,11 @@
<func:result select="$parsed_widgets/widget[@id = $id]"/>
+ <func:function name="func:is_descendant_path"> + <xsl:param name="descend"/> + <xsl:param name="ancest"/> + <func:result select="string-length($ancest) > 0 and starts-with($descend,$ancest)"/> <xsl:template mode="testtree" match="*">
<xsl:param name="indent" select="''"/>
<xsl:value-of select="$indent"/>
@@ -362,11 +324,6 @@
<xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages)"/>
<xsl:variable name="detachable_elements" select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"/>
- <func:function name="func:is_descendant_path">
- <xsl:param name="descend"/>
- <xsl:param name="ancest"/>
- <func:result select="string-length($ancest) > 0 and starts-with($descend,$ancest)"/>
<xsl:variable name="forEach_widgets_ids" select="$parsed_widgets/widget[@type = 'ForEach']/@id"/>
<xsl:variable name="forEach_widgets" select="$hmi_elements[@id = $forEach_widgets_ids]"/>
<xsl:variable name="in_forEach_widget_ids" select="func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id"/>
@@ -746,21 +703,28 @@
<xsl:template mode="widget_defs" match="widget[@type='ForEach']">
<xsl:param name="hmi_element"/>
<xsl:variable name="widgets" select="func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]"/>
- <xsl:text> frequency: 2,
- <xsl:text> dispatch: function(value) {
- <xsl:text> // do something
+ <xsl:variable name="class" select="arg[1]/@value"/> + <xsl:variable name="base_path" select="path/@value"/> + <xsl:variable name="hmi_index_base" select="$indexed_hmitree/*[@hmipath = $base_path]"/> + <xsl:variable name="hmi_tree_base" select="$hmitree/descendant-or-self::*[@path = $hmi_index_base/@path]"/> + <xsl:variable name="hmi_tree_items" select="$hmi_tree_base/*[@class = $class]"/> + <xsl:variable name="hmi_index_items" select="$indexed_hmitree/*[@path = $hmi_tree_items/@path]"/> + <xsl:variable name="items_paths" select="$hmi_index_items/@hmipath"/> + <xsl:for-each select="$hmi_index_items"> + <xsl:value-of select="@index"/> + <xsl:if test="position()!=last()"> - <xsl:variable name="class" select="arg[1]/@value"/>
<xsl:variable name="prefix" select="concat($class,':')"/>
<xsl:variable name="buttons_regex" select="concat('^',$prefix,'[+\-][0-9]+')"/>
<xsl:for-each select="$hmi_element/*[regexp:test(@inkscape:label, $buttons_regex)]">
@@ -787,19 +751,18 @@
- <xsl:variable name="base_path" select="path/@value"/>
<xsl:variable name="items_regex" select="concat('^',$prefix,'[0-9]+')"/>
<xsl:variable name="unordered_items" select="$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]"/>
<xsl:for-each select="$unordered_items">
<xsl:variable name="elt_label" select="concat($prefix, string(position()))"/>
<xsl:variable name="elt" select="$unordered_items[@inkscape:label = $elt_label]"/>
- <xsl:text> /* </xsl:text>
- <xsl:apply-templates mode="testtree" select="func:get_hmi_tree_elt($base_path)"/>
- <xsl:text> [ /* </xsl:text>
+ <xsl:variable name="pos" select="position()"/> + <xsl:variable name="item_path" select="$items_paths[$pos]"/> + <xsl:text> [ /* item="</xsl:text> <xsl:value-of select="$elt_label"/>
+ <xsl:text>" path="</xsl:text> + <xsl:value-of select="$item_path"/> <xsl:if test="count($elt)=0">
<xsl:message terminate="yes">
@@ -810,6 +773,19 @@
<xsl:for-each select="func:refered_elements($elt)[@id = $hmi_elements/@id][not(@id = $elt/@id)]">
+ <xsl:if test="not(func:is_descendant_path(func:widget(@id)/path/@value, $item_path))"> + <xsl:message terminate="yes"> + <xsl:text>Widget id="</xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>" label="</xsl:text> + <xsl:value-of select="@inkscape:label"/> + <xsl:text>" is having wrong path. Accroding to ForEach widget ancestor id="</xsl:text> + <xsl:value-of select="$hmi_element/@id"/> + <xsl:text>", path should be descendant of </xsl:text> + <xsl:value-of select="$item_path"/> <xsl:text> hmi_widgets["</xsl:text>
<xsl:value-of select="@id"/>
@@ -832,13 +808,13 @@
<xsl:template mode="widget_subscribe" match="widget[@type='ForEach']">
<xsl:text> sub: function(off){
- <xsl:text> subscribe.call(this,off);
+ <xsl:text> /*subscribe.call(this,off);*/ <xsl:text> unsub: function(){
- <xsl:text> unsubscribe.call(this);
+ <xsl:text> /*unsubscribe.call(this);*/ --- a/svghmi/hmi_tree.ysl2 Mon Mar 23 15:13:36 2020 +0100
+++ b/svghmi/hmi_tree.ysl2 Mon Mar 23 21:44:28 2020 +0100
@@ -52,36 +52,6 @@
-def "func:get_hmi_tree_elt" {
- param "root", "$hmitree";
- message > get_hmi_tree_elt «$path»
- if "not(starts-with($path, '/'))" error > Given path "«$path»" should start with a "/"
- const "stripped", "substring($path, 2)";
- when "contains($stripped, '/')" value "substring-before($stripped, '/')";
- otherwise value "$stripped";
- when "string-length($token) = 0"{
- const "rest", "substring-after($stripped, $token)";
- const "match", "$root/*[@name = $token]";
- when "string-length($rest) > 0"{
- result "func:get_hmi_tree_el($rest, $match)";
// "HMI:WidgetType:param1:param2@path1@path2"
@@ -139,6 +109,14 @@
+def "func:is_descendant_path" { + // TODO : use HMI tree to answer more accurately + result "string-length($ancest) > 0 and starts-with($descend,$ancest)"; template "*", mode="testtree"{
--- a/svghmi/widget_foreach.ysl2 Mon Mar 23 15:13:36 2020 +0100
+++ b/svghmi/widget_foreach.ysl2 Mon Mar 23 21:44:28 2020 +0100
@@ -2,14 +2,21 @@
template "widget[@type='ForEach']", mode="widget_defs" {
const "widgets", "func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]";
- | dispatch: function(value) {
+ const "class","arg[1]/@value"; + const "base_path","path/@value"; + const "hmi_index_base", "$indexed_hmitree/*[@hmipath = $base_path]"; + const "hmi_tree_base", "$hmitree/descendant-or-self::*[@path = $hmi_index_base/@path]"; + const "hmi_tree_items", "$hmi_tree_base/*[@class = $class]"; + const "hmi_index_items", "$indexed_hmitree/*[@path = $hmi_tree_items/@path]"; + const "items_paths", "$hmi_index_items/@hmipath"; + foreach "$hmi_index_items" { + | «@index»`if "position()!=last()" > ,` - const "class","arg[1]/@value";
const "prefix","concat($class,':')";
const "buttons_regex","concat('^',$prefix,'[+\-][0-9]+')";
foreach "$hmi_element/*[regexp:test(@inkscape:label, $buttons_regex)]" {
@@ -21,17 +28,18 @@
- const "base_path","path/@value";
const "items_regex","concat('^',$prefix,'[0-9]+')";
const "unordered_items","$hmi_element//*[regexp:test(@inkscape:label, $items_regex)]";
foreach "$unordered_items" {
const "elt_label","concat($prefix, string(position()))";
const "elt","$unordered_items[@inkscape:label = $elt_label]";
- | /* `apply "func:get_hmi_tree_elt($base_path)", mode="testtree";` */
+ const "pos","position()"; + const "item_path", "$items_paths[$pos]"; + | [ /* item="«$elt_label»" path="«$item_path»" */ if "count($elt)=0" error > Missing item labeled «$elt_label» in ForEach widget «$hmi_element/@id»
foreach "func:refered_elements($elt)[@id = $hmi_elements/@id][not(@id = $elt/@id)]" {
+ if "not(func:is_descendant_path(func:widget(@id)/path/@value, $item_path))" + error > Widget id="«@id»" label="«@inkscape:label»" is having wrong path. Accroding to ForEach widget ancestor id="«$hmi_element/@id»", path should be descendant of «$item_path». | hmi_widgets["«@id»"]`if "position()!=last()" > ,`
| ]`if "position()!=last()" > ,`
@@ -42,12 +50,12 @@
template "widget[@type='ForEach']", mode="widget_subscribe"{
- | subscribe.call(this,off);
+ | /*subscribe.call(this,off);*/ - | unsubscribe.call(this);
+ | /*unsubscribe.call(this);*/