SVGHMI: now generating JS object describing widgets and pointing to SVG elements svghmi
authorEdouard Tisserant
Mon, 07 Oct 2019 12:02:45 +0200
branchsvghmi
changeset 2791 d022523cb621
parent 2790 8fab1886ebec
child 2792 0c0d3895b036
SVGHMI: now generating JS object describing widgets and pointing to SVG elements
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/svghmi/gen_index_xhtml.xslt	Sat Oct 05 09:45:58 2019 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Mon Oct 07 12:02:45 2019 +0200
@@ -21,18 +21,35 @@
     </noindex>
   </xsl:variable>
   <xsl:variable name="categories" select="exsl:node-set($_categories)"/>
-  <xsl:variable name="indexed_hmitree">
+  <xsl:variable name="_indexed_hmitree">
     <xsl:apply-templates mode="index" select="$hmitree"/>
   </xsl:variable>
-  <xsl:template mode="index" match="node()">
+  <xsl:variable name="indexed_hmitree" select="exsl:node-set($_indexed_hmitree)"/>
+  <xsl:template mode="index" match="*">
     <xsl:param name="index" select="0"/>
+    <xsl:param name="parentpath" select="''"/>
     <xsl:variable name="content">
+      <xsl:variable name="path">
+        <xsl:choose>
+          <xsl:when test="local-name() = 'HMI_ROOT'">
+            <xsl:value-of select="$parentpath"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$parentpath"/>
+            <xsl:text>/</xsl:text>
+            <xsl:value-of select="@name"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
       <xsl:choose>
         <xsl:when test="not(local-name() = $categories/noindex)">
           <xsl:copy>
             <xsl:attribute name="index">
               <xsl:value-of select="$index"/>
             </xsl:attribute>
+            <xsl:attribute name="hmipath">
+              <xsl:value-of select="$path"/>
+            </xsl:attribute>
             <xsl:for-each select="@*">
               <xsl:copy/>
             </xsl:for-each>
@@ -41,6 +58,9 @@
         <xsl:otherwise>
           <xsl:apply-templates mode="index" select="*[1]">
             <xsl:with-param name="index" select="$index"/>
+            <xsl:with-param name="parentpath">
+              <xsl:value-of select="$path"/>
+            </xsl:with-param>
           </xsl:apply-templates>
         </xsl:otherwise>
       </xsl:choose>
@@ -48,11 +68,14 @@
     <xsl:copy-of select="$content"/>
     <xsl:apply-templates mode="index" select="following-sibling::*[1]">
       <xsl:with-param name="index" select="$index + count(exsl:node-set($content)/*)"/>
+      <xsl:with-param name="parentpath">
+        <xsl:value-of select="$parentpath"/>
+      </xsl:with-param>
     </xsl:apply-templates>
   </xsl:template>
-  <xsl:template match="@* | node()">
+  <xsl:template mode="identity_svg" match="@* | node()">
     <xsl:copy>
-      <xsl:apply-templates select="@* | node()"/>
+      <xsl:apply-templates mode="identity_svg" select="@* | node()"/>
     </xsl:copy>
   </xsl:template>
   <xsl:variable name="mark">
@@ -71,15 +94,48 @@
             <xsl:apply-templates mode="testtree" select="$hmitree"/>
           </xsl:comment>
           <xsl:comment>
-            <xsl:apply-templates mode="testtree" select="exsl:node-set($indexed_hmitree)"/>
+            <xsl:apply-templates mode="testtree" select="$indexed_hmitree"/>
           </xsl:comment>
-          <xsl:apply-templates select="@* | node()"/>
+          <xsl:apply-templates mode="identity_svg" select="@* | node()"/>
         </xsl:copy>
         <script>
           <xsl:text>var subscriptions = {
 </xsl:text>
-          <xsl:text>    return res;
-</xsl:text>
+          <xsl:variable name="svg" select="/"/>
+          <xsl:for-each select="$indexed_hmitree/*">
+            <xsl:value-of select="@index"/>
+            <xsl:text>: {
+</xsl:text>
+            <xsl:text>    name: "</xsl:text>
+            <xsl:value-of select="@name"/>
+            <xsl:text>",
+</xsl:text>
+            <xsl:text>    hmipath: "</xsl:text>
+            <xsl:value-of select="@hmipath"/>
+            <xsl:text>"
+</xsl:text>
+            <xsl:text>    ids: [
+</xsl:text>
+            <xsl:variable name="hmipath" select="@hmipath"/>
+            <xsl:for-each select="$svg//*[substring-after(@inkscape:label,'@') = $hmipath]">
+              <xsl:text>        "</xsl:text>
+              <xsl:value-of select="@id"/>
+              <xsl:text>"</xsl:text>
+              <xsl:if test="position()!=last()">
+                <xsl:text>,</xsl:text>
+              </xsl:if>
+              <xsl:text>
+</xsl:text>
+            </xsl:for-each>
+            <xsl:text>    ]
+</xsl:text>
+            <xsl:text>}</xsl:text>
+            <xsl:if test="position()!=last()">
+              <xsl:text>,</xsl:text>
+            </xsl:if>
+            <xsl:text>
+</xsl:text>
+          </xsl:for-each>
           <xsl:text>}
 </xsl:text>
           <xsl:text>// svghmi.js
--- a/svghmi/gen_index_xhtml.ysl2	Sat Oct 05 09:45:58 2019 +0200
+++ b/svghmi/gen_index_xhtml.ysl2	Mon Oct 07 12:02:45 2019 +0200
@@ -21,27 +21,35 @@
      * already parsed by python and presented as a list of 
      * <bbox x="0" y="0" w="42" h="42">
      */
-    variable "geometry", "ns:GetSVGGeometry()";
-    variable "hmitree", "ns:GetHMITree()";
+    const "geometry", "ns:GetSVGGeometry()";
+    const "hmitree", "ns:GetHMITree()";
 
-    variable "_categories" {
+    const "_categories" {
         noindex > HMI_ROOT
         noindex > HMI_LABEL
         noindex > HMI_CLASS
         noindex > HMI_PLC_STATUS
         noindex > HMI_CURRENT_PAGE
     }
-    variable "categories", "exsl:node-set($_categories)";
-    //variable "indexed_hmitree", "$hmitree[not(local-name() = $categories/noindex/text())]";
-    variable "indexed_hmitree" apply "$hmitree", mode="index";
+    const "categories", "exsl:node-set($_categories)";
+    //const "indexed_hmitree", "$hmitree[not(local-name() = $categories/noindex/text())]";
+    const "_indexed_hmitree" apply "$hmitree", mode="index";
+    const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";
 
-    template "node()", mode="index"{
+    template "*", mode="index"{
         param "index", "0";
-        variable "content" {
+        param "parentpath", "''";
+        const "content" {
+            const "path"
+                choose {
+                    when "local-name() = 'HMI_ROOT'" > «$parentpath»
+                    otherwise > «$parentpath»/«@name»
+                }
             choose {
                 when "not(local-name() = $categories/noindex)" {
                     xsl:copy {
                         attrib "index" > «$index»
+                        attrib "hmipath" > «$path»
                         foreach "@*" xsl:copy;
                     }
                     /* no node expected below value nodes */
@@ -49,6 +57,7 @@
                 otherwise {
                     apply "*[1]", mode="index"{
                         with "index", "$index";
+                        with "parentpath" > «$path»
                     }
                 }
             }
@@ -57,6 +66,7 @@
         copy "$content";
         apply "following-sibling::*[1]", mode="index" {
             with "index", "$index + count(exsl:node-set($content)/*)";
+            with "parentpath" > «$parentpath»
         }
     }
 
@@ -64,12 +74,12 @@
      *  - copy every attributes 
      *  - copy every sub-elements
      */
-    template "@* | node()" {
+    template "@* | node()", mode="identity_svg" {
       /* use real xsl:copy instead copy-of alias from yslt.yml2 */
-      xsl:copy apply "@* | node()";
+      xsl:copy apply "@* | node()", mode="identity_svg";
     }
 
-    variable "mark" > =HMI=\n
+    const "mark" > =HMI=\n
 
     /* copy root node and add geometry as comment for a test */
     template "/" 
@@ -84,9 +94,9 @@
                       apply "$hmitree", mode="testtree";
                   }
                   comment {
-                      apply "exsl:node-set($indexed_hmitree)", mode="testtree";
+                      apply "$indexed_hmitree", mode="testtree";
                   }
-                  apply "@* | node()";
+                  apply "@* | node()", mode="identity_svg";
               }
               script{
                   /* TODO : paste hmitree hash stored in hmi tree root node */
@@ -99,7 +109,7 @@
                       var Display;
                       var res = [];
                   ||
-                  variable "midmark" > \n«$mark»
+                  const "midmark" > \n«$mark»
                   apply """//*[contains(child::svg:desc, $midmark) or \
                                starts-with(child::svg:desc, $mark)]""",2 
                         mode="code_from_descs";
@@ -115,14 +125,24 @@
                     - widgets parameters
                   */
 
-                  ||
-                  var subscriptions = {
-                  ||
-                  //    apply "$hmitree", mode="subscription_";
-                  ||
-                      return res;
+                  | var subscriptions = {
+
+                  const "svg","/"; /* foreach loses document root */
+                  foreach "$indexed_hmitree/*" {
+                      | «@index»: {
+                      |     name: "«@name»",
+                      |     hmipath: "«@hmipath»"
+                      |     ids: [
+                      const "hmipath","@hmipath";
+                      foreach "$svg//*[substring-after(@inkscape:label,'@') = $hmipath]" {
+                      |         "«@id»"`if "position()!=last()" > ,`
+                      }
+                      |     ]
+                      | }`if "position()!=last()" > ,`
                   }
-                  ||
+
+                  | }
+
                   include text svghmi.js
               }
           }
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Sat Oct 05 09:45:58 2019 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Mon Oct 07 12:02:45 2019 +0200
@@ -80,8 +80,8 @@
      showgrid="false"
      units="px"
      inkscape:zoom="0.421875"
-     inkscape:cx="528.78019"
-     inkscape:cy="-50.076488"
+     inkscape:cx="486.11352"
+     inkscape:cy="131.25685"
      inkscape:window-width="1600"
      inkscape:window-height="886"
      inkscape:window-x="0"
@@ -180,7 +180,7 @@
      x="136.32812"
      y="218.24219"
      id="text5151"
-     inkscape:label="HMI:Input@/PRESSURETARGET"><tspan
+     inkscape:label="HMI:Input@/TARGETPRESSURE"><tspan
        sodipodi:role="line"
        id="tspan5149"
        x="136.32812"
@@ -201,7 +201,7 @@
   <g
      id="g4523"
      transform="matrix(3.7795276,0,0,3.7795276,308.51002,630.30393)"
-     inkscape:label="HMI:Meter@/hmi0/pump/pressure">
+     inkscape:label="HMI:Meter@/PUMP/ADDOUT">
     <path
        style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#3ee800;stroke-width:26.45833397;stroke-miterlimit:4;stroke-dasharray:2.64583333, 2.64583333;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
        id="path4499"