svghmi/gen_index_xhtml.xslt
branchsvghmi
changeset 2792 0c0d3895b036
parent 2791 d022523cb621
child 2793 2a97688c94c5
equal deleted inserted replaced
2791:d022523cb621 2792:0c0d3895b036
     1 <?xml version="1.0"?>
     1 <?xml version="1.0"?>
     2 <xsl:stylesheet xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" exclude-result-prefixes="ns" extension-element-prefixes="ns" version="1.0">
     2 <xsl:stylesheet xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns="beremiz" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" exclude-result-prefixes="ns str regexp exsl" extension-element-prefixes="ns" version="1.0">
     3   <xsl:output method="xml" cdata-section-elements="script"/>
     3   <xsl:output method="xml" cdata-section-elements="script"/>
     4   <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
     4   <xsl:variable name="geometry" select="ns:GetSVGGeometry()"/>
     5   <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
     5   <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
     6   <xsl:variable name="_categories">
     6   <xsl:variable name="_categories">
     7     <noindex>
     7     <noindex>
    97             <xsl:apply-templates mode="testtree" select="$indexed_hmitree"/>
    97             <xsl:apply-templates mode="testtree" select="$indexed_hmitree"/>
    98           </xsl:comment>
    98           </xsl:comment>
    99           <xsl:apply-templates mode="identity_svg" select="@* | node()"/>
    99           <xsl:apply-templates mode="identity_svg" select="@* | node()"/>
   100         </xsl:copy>
   100         </xsl:copy>
   101         <script>
   101         <script>
   102           <xsl:text>var subscriptions = {
   102           <xsl:call-template name="scripts"/>
   103 </xsl:text>
       
   104           <xsl:variable name="svg" select="/"/>
       
   105           <xsl:for-each select="$indexed_hmitree/*">
       
   106             <xsl:value-of select="@index"/>
       
   107             <xsl:text>: {
       
   108 </xsl:text>
       
   109             <xsl:text>    name: "</xsl:text>
       
   110             <xsl:value-of select="@name"/>
       
   111             <xsl:text>",
       
   112 </xsl:text>
       
   113             <xsl:text>    hmipath: "</xsl:text>
       
   114             <xsl:value-of select="@hmipath"/>
       
   115             <xsl:text>"
       
   116 </xsl:text>
       
   117             <xsl:text>    ids: [
       
   118 </xsl:text>
       
   119             <xsl:variable name="hmipath" select="@hmipath"/>
       
   120             <xsl:for-each select="$svg//*[substring-after(@inkscape:label,'@') = $hmipath]">
       
   121               <xsl:text>        "</xsl:text>
       
   122               <xsl:value-of select="@id"/>
       
   123               <xsl:text>"</xsl:text>
       
   124               <xsl:if test="position()!=last()">
       
   125                 <xsl:text>,</xsl:text>
       
   126               </xsl:if>
       
   127               <xsl:text>
       
   128 </xsl:text>
       
   129             </xsl:for-each>
       
   130             <xsl:text>    ]
       
   131 </xsl:text>
       
   132             <xsl:text>}</xsl:text>
       
   133             <xsl:if test="position()!=last()">
       
   134               <xsl:text>,</xsl:text>
       
   135             </xsl:if>
       
   136             <xsl:text>
       
   137 </xsl:text>
       
   138           </xsl:for-each>
       
   139           <xsl:text>}
       
   140 </xsl:text>
       
   141           <xsl:text>// svghmi.js
       
   142 </xsl:text>
       
   143           <xsl:text>
       
   144 </xsl:text>
       
   145           <xsl:text>(function(){
       
   146 </xsl:text>
       
   147           <xsl:text>    // Open WebSocket to relative "/ws" address
       
   148 </xsl:text>
       
   149           <xsl:text>    var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
       
   150 </xsl:text>
       
   151           <xsl:text>
       
   152 </xsl:text>
       
   153           <xsl:text>    // Register message reception handler 
       
   154 </xsl:text>
       
   155           <xsl:text>    ws.onmessage = function (evt) {
       
   156 </xsl:text>
       
   157           <xsl:text>        // TODO : dispatch and cache hmi tree updates
       
   158 </xsl:text>
       
   159           <xsl:text>
       
   160 </xsl:text>
       
   161           <xsl:text>        var received_msg = evt.data;
       
   162 </xsl:text>
       
   163           <xsl:text>        // TODO : check for hmitree hash header
       
   164 </xsl:text>
       
   165           <xsl:text>        //        if not matching, reload page
       
   166 </xsl:text>
       
   167           <xsl:text>        alert("Message is received..."+received_msg); 
       
   168 </xsl:text>
       
   169           <xsl:text>    };
       
   170 </xsl:text>
       
   171           <xsl:text>
       
   172 </xsl:text>
       
   173           <xsl:text>    // Once connection established
       
   174 </xsl:text>
       
   175           <xsl:text>    ws.onopen = function (evt) {
       
   176 </xsl:text>
       
   177           <xsl:text>        // TODO : enable the HMI (was previously offline, or just starts)
       
   178 </xsl:text>
       
   179           <xsl:text>        //        show main page
       
   180 </xsl:text>
       
   181           <xsl:text>
       
   182 </xsl:text>
       
   183           <xsl:text>
       
   184 </xsl:text>
       
   185           <xsl:text>        // TODO : prefix with hmitree hash header
       
   186 </xsl:text>
       
   187           <xsl:text>        ws.send("test");
       
   188 </xsl:text>
       
   189           <xsl:text>    };
       
   190 </xsl:text>
       
   191           <xsl:text>
       
   192 </xsl:text>
       
   193           <xsl:text>    var pending_updates = {};
       
   194 </xsl:text>
       
   195           <xsl:text>    
       
   196 </xsl:text>
       
   197           <xsl:text>    // subscription state, as it should be in hmi server
       
   198 </xsl:text>
       
   199           <xsl:text>    // expected {index:period}
       
   200 </xsl:text>
       
   201           <xsl:text>    var subscriptions = {};
       
   202 </xsl:text>
       
   203           <xsl:text>
       
   204 </xsl:text>
       
   205           <xsl:text>
       
   206 </xsl:text>
       
   207           <xsl:text>    // subscription state as needed by widget now
       
   208 </xsl:text>
       
   209           <xsl:text>    // expected {index:[widgets]};
       
   210 </xsl:text>
       
   211           <xsl:text>    var subscribers = {};
       
   212 </xsl:text>
       
   213           <xsl:text>
       
   214 </xsl:text>
       
   215           <xsl:text>    // return the diff in between curently subscribed and subscription
       
   216 </xsl:text>
       
   217           <xsl:text>    function update_subscriptions() {
       
   218 </xsl:text>
       
   219           <xsl:text>        let result = [];
       
   220 </xsl:text>
       
   221           <xsl:text>        Object.keys(subscribers).forEach(index =&gt; {
       
   222 </xsl:text>
       
   223           <xsl:text>
       
   224 </xsl:text>
       
   225           <xsl:text>            let previous_period = subscriptions[index];
       
   226 </xsl:text>
       
   227           <xsl:text>            let new_period = Math.min(...widgets.map(widget =&gt; widget.period));
       
   228 </xsl:text>
       
   229           <xsl:text>
       
   230 </xsl:text>
       
   231           <xsl:text>            if(previous_period != new_period) 
       
   232 </xsl:text>
       
   233           <xsl:text>                result.push({index: index, period: new_period});
       
   234 </xsl:text>
       
   235           <xsl:text>        })
       
   236 </xsl:text>
       
   237           <xsl:text>    }
       
   238 </xsl:text>
       
   239           <xsl:text>
       
   240 </xsl:text>
       
   241           <xsl:text>
       
   242 </xsl:text>
       
   243           <xsl:text>    function update_value(index, value) {
       
   244 </xsl:text>
       
   245           <xsl:text>
       
   246 </xsl:text>
       
   247           <xsl:text>    };
       
   248 </xsl:text>
       
   249           <xsl:text>
       
   250 </xsl:text>
       
   251           <xsl:text>})();
       
   252 </xsl:text>
       
   253         </script>
   103         </script>
   254       </body>
   104       </body>
   255     </html>
   105     </html>
   256   </xsl:template>
   106   </xsl:template>
       
   107   <xsl:template name="scripts">
       
   108     <xsl:text>var hmi_index = {
       
   109 </xsl:text>
       
   110     <xsl:variable name="svg" select="/"/>
       
   111     <xsl:for-each select="$indexed_hmitree/*">
       
   112       <xsl:value-of select="@index"/>
       
   113       <xsl:text>: {
       
   114 </xsl:text>
       
   115       <xsl:text>    name: "</xsl:text>
       
   116       <xsl:value-of select="@name"/>
       
   117       <xsl:text>",
       
   118 </xsl:text>
       
   119       <xsl:text>    hmipath: "</xsl:text>
       
   120       <xsl:value-of select="@hmipath"/>
       
   121       <xsl:text>"
       
   122 </xsl:text>
       
   123       <xsl:text>    ids: [
       
   124 </xsl:text>
       
   125       <xsl:variable name="hmipath" select="@hmipath"/>
       
   126       <xsl:for-each select="$svg//*[substring-after(@inkscape:label,'@') = $hmipath]">
       
   127         <xsl:text>        "</xsl:text>
       
   128         <xsl:value-of select="@id"/>
       
   129         <xsl:text>"</xsl:text>
       
   130         <xsl:if test="position()!=last()">
       
   131           <xsl:text>,</xsl:text>
       
   132         </xsl:if>
       
   133         <xsl:text>
       
   134 </xsl:text>
       
   135       </xsl:for-each>
       
   136       <xsl:text>    ]
       
   137 </xsl:text>
       
   138       <xsl:text>}</xsl:text>
       
   139       <xsl:if test="position()!=last()">
       
   140         <xsl:text>,</xsl:text>
       
   141       </xsl:if>
       
   142       <xsl:text>
       
   143 </xsl:text>
       
   144     </xsl:for-each>
       
   145     <xsl:text>}
       
   146 </xsl:text>
       
   147     <xsl:text>
       
   148 </xsl:text>
       
   149     <xsl:text>var page_desc = {
       
   150 </xsl:text>
       
   151     <xsl:for-each select="//*[starts-with(@inkscape:label,'HMI:')]">
       
   152       <xsl:value-of select="@inkscape:label"/>
       
   153       <xsl:text>
       
   154 </xsl:text>
       
   155       <xsl:variable name="ast">
       
   156         <xsl:call-template name="parse_label">
       
   157           <xsl:with-param name="label" select="@inkscape:label"/>
       
   158         </xsl:call-template>
       
   159       </xsl:variable>
       
   160       <xsl:apply-templates mode="testtree" select="exsl:node-set($ast)"/>
       
   161     </xsl:for-each>
       
   162     <xsl:text>}
       
   163 </xsl:text>
       
   164     <xsl:text>// svghmi.js
       
   165 </xsl:text>
       
   166     <xsl:text>
       
   167 </xsl:text>
       
   168     <xsl:text>(function(){
       
   169 </xsl:text>
       
   170     <xsl:text>    // Open WebSocket to relative "/ws" address
       
   171 </xsl:text>
       
   172     <xsl:text>    var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
       
   173 </xsl:text>
       
   174     <xsl:text>
       
   175 </xsl:text>
       
   176     <xsl:text>    // Register message reception handler 
       
   177 </xsl:text>
       
   178     <xsl:text>    ws.onmessage = function (evt) {
       
   179 </xsl:text>
       
   180     <xsl:text>        // TODO : dispatch and cache hmi tree updates
       
   181 </xsl:text>
       
   182     <xsl:text>
       
   183 </xsl:text>
       
   184     <xsl:text>        var received_msg = evt.data;
       
   185 </xsl:text>
       
   186     <xsl:text>        // TODO : check for hmitree hash header
       
   187 </xsl:text>
       
   188     <xsl:text>        //        if not matching, reload page
       
   189 </xsl:text>
       
   190     <xsl:text>        alert("Message is received..."+received_msg); 
       
   191 </xsl:text>
       
   192     <xsl:text>    };
       
   193 </xsl:text>
       
   194     <xsl:text>
       
   195 </xsl:text>
       
   196     <xsl:text>    // Once connection established
       
   197 </xsl:text>
       
   198     <xsl:text>    ws.onopen = function (evt) {
       
   199 </xsl:text>
       
   200     <xsl:text>        // TODO : enable the HMI (was previously offline, or just starts)
       
   201 </xsl:text>
       
   202     <xsl:text>        //        show main page
       
   203 </xsl:text>
       
   204     <xsl:text>
       
   205 </xsl:text>
       
   206     <xsl:text>
       
   207 </xsl:text>
       
   208     <xsl:text>        // TODO : prefix with hmitree hash header
       
   209 </xsl:text>
       
   210     <xsl:text>        ws.send("test");
       
   211 </xsl:text>
       
   212     <xsl:text>    };
       
   213 </xsl:text>
       
   214     <xsl:text>
       
   215 </xsl:text>
       
   216     <xsl:text>    var pending_updates = {};
       
   217 </xsl:text>
       
   218     <xsl:text>    
       
   219 </xsl:text>
       
   220     <xsl:text>    // subscription state, as it should be in hmi server
       
   221 </xsl:text>
       
   222     <xsl:text>    // expected {index:period}
       
   223 </xsl:text>
       
   224     <xsl:text>    const subscriptions = new Map();
       
   225 </xsl:text>
       
   226     <xsl:text>
       
   227 </xsl:text>
       
   228     <xsl:text>
       
   229 </xsl:text>
       
   230     <xsl:text>    // subscription state as needed by widget now
       
   231 </xsl:text>
       
   232     <xsl:text>    // expected {index:[widgets]};
       
   233 </xsl:text>
       
   234     <xsl:text>    var subscribers = {};
       
   235 </xsl:text>
       
   236     <xsl:text>
       
   237 </xsl:text>
       
   238     <xsl:text>    // return the diff in between curently subscribed and subscription
       
   239 </xsl:text>
       
   240     <xsl:text>    function update_subscriptions() {
       
   241 </xsl:text>
       
   242     <xsl:text>        let delta = [];
       
   243 </xsl:text>
       
   244     <xsl:text>        Object.keys(subscribers).forEach(index =&gt; {
       
   245 </xsl:text>
       
   246     <xsl:text>
       
   247 </xsl:text>
       
   248     <xsl:text>            let previous_period = subscriptions.get(index);
       
   249 </xsl:text>
       
   250     <xsl:text>            delete subscriptions[index];
       
   251 </xsl:text>
       
   252     <xsl:text>
       
   253 </xsl:text>
       
   254     <xsl:text>            let new_period = Math.min(...widgets.map(widget =&gt; widget.period));
       
   255 </xsl:text>
       
   256     <xsl:text>
       
   257 </xsl:text>
       
   258     <xsl:text>            if(previous_period != new_period) 
       
   259 </xsl:text>
       
   260     <xsl:text>                delta.push({index: index, period: new_period});
       
   261 </xsl:text>
       
   262     <xsl:text>        })
       
   263 </xsl:text>
       
   264     <xsl:text>        return result;
       
   265 </xsl:text>
       
   266     <xsl:text>    }
       
   267 </xsl:text>
       
   268     <xsl:text>
       
   269 </xsl:text>
       
   270     <xsl:text>
       
   271 </xsl:text>
       
   272     <xsl:text>    function update_value(index, value) {
       
   273 </xsl:text>
       
   274     <xsl:text>
       
   275 </xsl:text>
       
   276     <xsl:text>    };
       
   277 </xsl:text>
       
   278     <xsl:text>
       
   279 </xsl:text>
       
   280     <xsl:text>    function switch_page(page_name) {
       
   281 </xsl:text>
       
   282     <xsl:text>
       
   283 </xsl:text>
       
   284     <xsl:text>    };
       
   285 </xsl:text>
       
   286     <xsl:text>
       
   287 </xsl:text>
       
   288     <xsl:text>})();
       
   289 </xsl:text>
       
   290   </xsl:template>
       
   291   <xsl:template name="parse_label">
       
   292     <xsl:param name="label"/>
       
   293     <xsl:variable name="description" select="substring-after($label,'HMI:')"/>
       
   294     <xsl:variable name="_args" select="substring-before($description,'@')"/>
       
   295     <xsl:variable name="args">
       
   296       <xsl:choose>
       
   297         <xsl:when test="$_args">
       
   298           <xsl:value-of select="$_args"/>
       
   299         </xsl:when>
       
   300         <xsl:otherwise>
       
   301           <xsl:value-of select="$description"/>
       
   302         </xsl:otherwise>
       
   303       </xsl:choose>
       
   304     </xsl:variable>
       
   305     <xsl:variable name="_type" select="substring-before($args,':')"/>
       
   306     <xsl:variable name="type">
       
   307       <xsl:choose>
       
   308         <xsl:when test="$_type">
       
   309           <xsl:value-of select="$_type"/>
       
   310         </xsl:when>
       
   311         <xsl:otherwise>
       
   312           <xsl:value-of select="$args"/>
       
   313         </xsl:otherwise>
       
   314       </xsl:choose>
       
   315     </xsl:variable>
       
   316     <xsl:if test="$type">
       
   317       <widget>
       
   318         <xsl:attribute name="type">
       
   319           <xsl:value-of select="$type"/>
       
   320         </xsl:attribute>
       
   321         <xsl:for-each select="str:split($args, ':')">
       
   322           <arg>
       
   323             <xsl:attribute name="value">
       
   324               <xsl:value-of select="."/>
       
   325             </xsl:attribute>
       
   326           </arg>
       
   327         </xsl:for-each>
       
   328         <xsl:variable name="paths" select="substring-after($description,'@')"/>
       
   329         <xsl:for-each select="str:split($paths, '@')">
       
   330           <path>
       
   331             <xsl:attribute name="value">
       
   332               <xsl:value-of select="."/>
       
   333             </xsl:attribute>
       
   334           </path>
       
   335         </xsl:for-each>
       
   336       </widget>
       
   337     </xsl:if>
       
   338   </xsl:template>
       
   339   <xsl:template mode="page_desc" match="*"/>
   257   <xsl:template mode="code_from_descs" match="*">
   340   <xsl:template mode="code_from_descs" match="*">
   258     <xsl:text>{
   341     <xsl:text>{
   259 </xsl:text>
   342 </xsl:text>
   260     <xsl:text>    var path, role, name, priv;
   343     <xsl:text>    var path, role, name, priv;
   261 </xsl:text>
   344 </xsl:text>