--- a/svghmi/gen_index_xhtml.xslt Tue Feb 16 11:32:37 2021 +0100
+++ b/svghmi/gen_index_xhtml.xslt Tue Feb 16 11:35:56 2021 +0100
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:str="http://exslt.org/strings" xmlns:func="http://exslt.org/functions" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:debug="debug" xmlns:preamble="preamble" xmlns:declarations="declarations" xmlns:definitions="definitions" xmlns:epilogue="epilogue" xmlns:ns="beremiz" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
- <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
+<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 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:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0">
+ <xsl:output method="xml" cdata-section-elements="xhtml:script"/>
<xsl:variable name="svg" select="/svg:svg"/>
<xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
<xsl:variable name="hmitree" select="ns:GetHMITree()"/>
@@ -1135,6 +1135,8 @@
</xsl:text>
<xsl:text>
</xsl:text>
+ <xsl:text>
+</xsl:text>
<xsl:text>let hmi_locals = {};
</xsl:text>
<xsl:text>var last_remote_index = hmitree_types.length - 1;
@@ -1206,6 +1208,8 @@
</xsl:text>
<xsl:text>var cache = hmitree_types.map(_ignored => undefined);
</xsl:text>
+ <xsl:text>var updates = {};
+</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>function page_local_index(varname, pagename){
@@ -1329,15 +1333,15 @@
</xsl:text>
<xsl:text> /* flush updates pending because of inhibition */
</xsl:text>
- <xsl:text> let inhibition = this.inhibit[index];
+ <xsl:text> let inhibition = this.inhibit[i];
</xsl:text>
<xsl:text> if(inhibition != undefined){
</xsl:text>
<xsl:text> clearTimeout(inhibition);
</xsl:text>
- <xsl:text> this.lastapply[index] = undefined;
-</xsl:text>
- <xsl:text> this.unhinibit(index);
+ <xsl:text> this.lastapply[i] = undefined;
+</xsl:text>
+ <xsl:text> this.unhinibit(i);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -1665,7 +1669,7 @@
</xsl:text>
</xsl:template>
<xsl:variable name="excluded_types" select="str:split('Page VarInit VarInitPersistent')"/>
- <xsl:key name="TypesKey" match="widget" use="@type"/>
+ <xsl:key use="@type" name="TypesKey" match="widget"/>
<declarations:hmi-classes/>
<xsl:template match="declarations:hmi-classes">
<xsl:text>
@@ -2876,7 +2880,7 @@
</xsl:text>
<xsl:text> this.fields[index] = value;
</xsl:text>
- <xsl:text> this.element.textContent = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
+ <xsl:text> this.request_animate();
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -2885,11 +2889,22 @@
</xsl:template>
<xsl:template mode="widget_defs" match="widget[@type='Display']">
<xsl:param name="hmi_element"/>
- <xsl:if test="$hmi_element[not(self::svg:text)]">
+ <xsl:variable name="format">
+ <xsl:call-template name="defs_by_labels">
+ <xsl:with-param name="hmi_element" select="$hmi_element"/>
+ <xsl:with-param name="labels">
+ <xsl:text>format</xsl:text>
+ </xsl:with-param>
+ <xsl:with-param name="mandatory" select="'no'"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="has_format" select="string-length($format)>0"/>
+ <xsl:value-of select="$format"/>
+ <xsl:if test="$hmi_element[not(self::svg:text)] and not($has_format)">
<xsl:message terminate="yes">
<xsl:text>Display Widget id="</xsl:text>
<xsl:value-of select="$hmi_element/@id"/>
- <xsl:text>" is not a svg::text element</xsl:text>
+ <xsl:text>" must be a svg::text element itself or a group containing a svg:text element labelled "format"</xsl:text>
</xsl:message>
</xsl:if>
<xsl:variable name="field_initializer">
@@ -2911,6 +2926,42 @@
<xsl:value-of select="$field_initializer"/>
<xsl:text>],
</xsl:text>
+ <xsl:text> animate: function(){
+</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$has_format">
+ <xsl:text> if(this.format_elt.getAttribute("lang")) {
+</xsl:text>
+ <xsl:text> this.format = svg_text_to_multiline(this.format_elt);
+</xsl:text>
+ <xsl:text> this.format_elt.removeAttribute("lang");
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> let str = vsprintf(this.format,this.fields);
+</xsl:text>
+ <xsl:text> multiline_to_svg_text(this.format_elt, str);
+</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> let str = this.args.length == 1 ? vsprintf(this.args[0],this.fields) : this.fields.join(' ');
+</xsl:text>
+ <xsl:text> multiline_to_svg_text(this.element, str);
+</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text> },
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:if test="$has_format">
+ <xsl:text> init: function() {
+</xsl:text>
+ <xsl:text> this.format = svg_text_to_multiline(this.format_elt);
+</xsl:text>
+ <xsl:text> },
+</xsl:text>
+ </xsl:if>
</xsl:template>
<preamble:display/>
<xsl:template match="preamble:display">
@@ -5602,15 +5653,13 @@
</xsl:text>
<xsl:text> case 0:
</xsl:text>
- <xsl:text> if (Math.round(this.position) != value)
-</xsl:text>
- <xsl:text> this.position = value;
+ <xsl:text> this.position = value;
</xsl:text>
<xsl:text> break;
</xsl:text>
<xsl:text> case 1:
</xsl:text>
- <xsl:text> this.range = value;
+ <xsl:text> this.range = Math.max(1,value);
</xsl:text>
<xsl:text> break;
</xsl:text>
@@ -5688,9 +5737,9 @@
</xsl:text>
<xsl:text> apply_position(position){
</xsl:text>
- <xsl:text> this.position = Math.max(Math.min(position, this.range), 0);
-</xsl:text>
- <xsl:text> this.apply_hmi_value(0, Math.round(this.position));
+ <xsl:text> this.position = Math.round(Math.max(Math.min(position, this.range), 0));
+</xsl:text>
+ <xsl:text> this.apply_hmi_value(0, this.position);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -5726,6 +5775,8 @@
</xsl:text>
<xsl:text> svg_root.addEventListener("pointermove", this.bound_drag, true);
</xsl:text>
+ <xsl:text> this.dragpos = this.position;
+</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
@@ -5750,7 +5801,9 @@
</xsl:text>
<xsl:text> let movement = point.matrixTransform(this.invctm).y;
</xsl:text>
- <xsl:text> this.apply_position(this.position + movement * units / pixels);
+ <xsl:text> this.dragpos += movement * units / pixels;
+</xsl:text>
+ <xsl:text> this.apply_position(this.dragpos);
</xsl:text>
<xsl:text> }
</xsl:text>
@@ -6653,7 +6706,7 @@
<xsl:comment>
<xsl:apply-templates select="document('')/*/debug:*"/>
</xsl:comment>
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <html xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/1999/xhtml">
<head/>
<body style="margin:0;overflow:hidden;user-select:none;touch-action:none;">
<xsl:copy-of select="$result_svg"/>
@@ -6694,14 +6747,10 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text>var updates = {};
-</xsl:text>
<xsl:text>var need_cache_apply = [];
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text>function dispatch_value(index, value) {
</xsl:text>
<xsl:text> let widgets = subscribers(index);
@@ -6982,6 +7031,8 @@
</xsl:text>
<xsl:text> NODE: (truth) => new Int16Array([truth]),
</xsl:text>
+ <xsl:text> REAL: (number) => new Float32Array([number]),
+</xsl:text>
<xsl:text> STRING: (str) => {
</xsl:text>
<xsl:text> // beremiz default string max size is 128
@@ -7102,7 +7153,19 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text>var translated = false;
+ <xsl:text>function svg_text_to_multiline(elt) {
+</xsl:text>
+ <xsl:text> return(Array.prototype.map.call(elt.children, x=>x.textContent).join("\n"));
+</xsl:text>
+ <xsl:text>}
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function multiline_to_svg_text(elt, str) {
+</xsl:text>
+ <xsl:text> str.split('\n').map((line,i) => {elt.children[i].textContent = line;});
+</xsl:text>
+ <xsl:text>}
</xsl:text>
<xsl:text>
</xsl:text>
@@ -7116,350 +7179,352 @@
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> if (!translated) {
-</xsl:text>
- <xsl:text> translated = true;
-</xsl:text>
- <xsl:text> for (let translation of translations) {
-</xsl:text>
- <xsl:text> let [objs] = translation;
-</xsl:text>
- <xsl:text> translation.push(Array.prototype.map.call(objs[0].children, x=>x.textContent).join("\n"));
+ <xsl:text> for (let translation of translations) {
+</xsl:text>
+ <xsl:text> let [objs, msgs, orig] = translation;
+</xsl:text>
+ <xsl:text> let msg = langnum == 0 ? orig : msgs[langnum - 1];
+</xsl:text>
+ <xsl:text> for (let obj of objs) {
+</xsl:text>
+ <xsl:text> multiline_to_svg_text(obj, msg);
+</xsl:text>
+ <xsl:text> obj.setAttribute("lang",langnum);
</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> for (let translation of translations) {
-</xsl:text>
- <xsl:text> let [objs, msgs, orig] = translation;
-</xsl:text>
- <xsl:text> let msg = langnum == 0 ? orig : msgs[langnum - 1];
-</xsl:text>
- <xsl:text> for (let obj of objs) {
-</xsl:text>
- <xsl:text> msg.split('\n').map((line,i) => {obj.children[i].textContent = line;});
+ <xsl:text> current_lang = langnum;
+</xsl:text>
+ <xsl:text>}
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>// backup original texts
+</xsl:text>
+ <xsl:text>for (let translation of translations) {
+</xsl:text>
+ <xsl:text> let [objs] = translation;
+</xsl:text>
+ <xsl:text> translation.push(svg_text_to_multiline(objs[0]));
+</xsl:text>
+ <xsl:text>}
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>var lang_local_index = hmi_local_index("lang");
+</xsl:text>
+ <xsl:text>subscribers(lang_local_index).add({
+</xsl:text>
+ <xsl:text> indexes: [lang_local_index],
+</xsl:text>
+ <xsl:text> new_hmi_value: function(index, value, oldval) {
+</xsl:text>
+ <xsl:text> switch_langnum(value);
+</xsl:text>
+ <xsl:text> switch_page();
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>});
+</xsl:text>
+ <xsl:text>var current_lang = 0;
+</xsl:text>
+ <xsl:text>switch_langnum(cache[lang_local_index]);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function update_subscriptions() {
+</xsl:text>
+ <xsl:text> let delta = [];
+</xsl:text>
+ <xsl:text> for(let index in subscriptions){
+</xsl:text>
+ <xsl:text> let widgets = subscribers(index);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // periods are in ms
+</xsl:text>
+ <xsl:text> let previous_period = get_subscription_period(index);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // subscribing with a zero period is unsubscribing
+</xsl:text>
+ <xsl:text> let new_period = 0;
+</xsl:text>
+ <xsl:text> if(widgets.size > 0) {
+</xsl:text>
+ <xsl:text> let maxfreq = 0;
+</xsl:text>
+ <xsl:text> for(let widget of widgets){
+</xsl:text>
+ <xsl:text> let wf = widget.frequency;
+</xsl:text>
+ <xsl:text> if(wf != undefined && maxfreq < wf)
+</xsl:text>
+ <xsl:text> maxfreq = wf;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(maxfreq != 0)
+</xsl:text>
+ <xsl:text> new_period = 1000/maxfreq;
</xsl:text>
<xsl:text> }
</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(previous_period != new_period) {
+</xsl:text>
+ <xsl:text> set_subscription_period(index, new_period);
+</xsl:text>
+ <xsl:text> if(index <= last_remote_index){
+</xsl:text>
+ <xsl:text> delta.push(
+</xsl:text>
+ <xsl:text> new Uint8Array([2]), /* subscribe = 2 */
+</xsl:text>
+ <xsl:text> new Uint32Array([index]),
+</xsl:text>
+ <xsl:text> new Uint16Array([new_period]));
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> current_lang = langnum;
+ <xsl:text> send_blob(delta);
+</xsl:text>
+ <xsl:text>};
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function send_hmi_value(index, value) {
+</xsl:text>
+ <xsl:text> if(index > last_remote_index){
+</xsl:text>
+ <xsl:text> updates[index] = value;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(persistent_indexes.has(index)){
+</xsl:text>
+ <xsl:text> let varname = persistent_indexes.get(index);
+</xsl:text>
+ <xsl:text> document.cookie = varname+"="+value+"; max-age=3153600000";
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> requestHMIAnimation();
+</xsl:text>
+ <xsl:text> return;
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> let iectype = hmitree_types[index];
+</xsl:text>
+ <xsl:text> let tobinary = typedarray_types[iectype];
+</xsl:text>
+ <xsl:text> send_blob([
+</xsl:text>
+ <xsl:text> new Uint8Array([0]), /* setval = 0 */
+</xsl:text>
+ <xsl:text> new Uint32Array([index]),
+</xsl:text>
+ <xsl:text> tobinary(value)]);
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
+</xsl:text>
+ <xsl:text> // cache[index] = value;
+</xsl:text>
+ <xsl:text>};
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function apply_hmi_value(index, new_val) {
+</xsl:text>
+ <xsl:text> let old_val = cache[index]
+</xsl:text>
+ <xsl:text> if(new_val != undefined && old_val != new_val)
+</xsl:text>
+ <xsl:text> send_hmi_value(index, new_val);
+</xsl:text>
+ <xsl:text> return new_val;
</xsl:text>
<xsl:text>}
</xsl:text>
- <xsl:text>var lang_local_index = hmi_local_index("lang");
-</xsl:text>
- <xsl:text>subscribers(lang_local_index).add({
-</xsl:text>
- <xsl:text> indexes: [lang_local_index],
-</xsl:text>
- <xsl:text> new_hmi_value: function(index, value, oldval) {
-</xsl:text>
- <xsl:text> switch_langnum(value);
+ <xsl:text>
+</xsl:text>
+ <xsl:text>const quotes = {"'":null, '"':null};
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function eval_operation_string(old_val, opstr) {
+</xsl:text>
+ <xsl:text> let op = opstr[0];
+</xsl:text>
+ <xsl:text> let given_val;
+</xsl:text>
+ <xsl:text> if(opstr.length < 2)
+</xsl:text>
+ <xsl:text> return undefined;
+</xsl:text>
+ <xsl:text> if(opstr[1] in quotes){
+</xsl:text>
+ <xsl:text> if(opstr.length < 3)
+</xsl:text>
+ <xsl:text> return undefined;
+</xsl:text>
+ <xsl:text> if(opstr[opstr.length-1] == opstr[1]){
+</xsl:text>
+ <xsl:text> given_val = opstr.slice(2,opstr.length-1);
+</xsl:text>
+ <xsl:text> }
+</xsl:text>
+ <xsl:text> } else {
+</xsl:text>
+ <xsl:text> given_val = Number(opstr.slice(1));
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text>});
-</xsl:text>
- <xsl:text>var current_lang = 0;
-</xsl:text>
- <xsl:text>switch_langnum(cache[lang_local_index]);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>function update_subscriptions() {
-</xsl:text>
- <xsl:text> let delta = [];
-</xsl:text>
- <xsl:text> for(let index in subscriptions){
-</xsl:text>
- <xsl:text> let widgets = subscribers(index);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> // periods are in ms
-</xsl:text>
- <xsl:text> let previous_period = get_subscription_period(index);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> // subscribing with a zero period is unsubscribing
-</xsl:text>
- <xsl:text> let new_period = 0;
-</xsl:text>
- <xsl:text> if(widgets.size > 0) {
-</xsl:text>
- <xsl:text> let maxfreq = 0;
-</xsl:text>
- <xsl:text> for(let widget of widgets){
-</xsl:text>
- <xsl:text> let wf = widget.frequency;
-</xsl:text>
- <xsl:text> if(wf != undefined && maxfreq < wf)
-</xsl:text>
- <xsl:text> maxfreq = wf;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(maxfreq != 0)
-</xsl:text>
- <xsl:text> new_period = 1000/maxfreq;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(previous_period != new_period) {
-</xsl:text>
- <xsl:text> set_subscription_period(index, new_period);
-</xsl:text>
- <xsl:text> if(index <= last_remote_index){
-</xsl:text>
- <xsl:text> delta.push(
-</xsl:text>
- <xsl:text> new Uint8Array([2]), /* subscribe = 2 */
-</xsl:text>
- <xsl:text> new Uint32Array([index]),
-</xsl:text>
- <xsl:text> new Uint16Array([new_period]));
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text> }
+ <xsl:text> let new_val;
+</xsl:text>
+ <xsl:text> switch(op){
+</xsl:text>
+ <xsl:text> case "=":
+</xsl:text>
+ <xsl:text> new_val = given_val;
+</xsl:text>
+ <xsl:text> break;
+</xsl:text>
+ <xsl:text> case "+":
+</xsl:text>
+ <xsl:text> new_val = old_val + given_val;
+</xsl:text>
+ <xsl:text> break;
+</xsl:text>
+ <xsl:text> case "-":
+</xsl:text>
+ <xsl:text> new_val = old_val - given_val;
+</xsl:text>
+ <xsl:text> break;
+</xsl:text>
+ <xsl:text> case "*":
+</xsl:text>
+ <xsl:text> new_val = old_val * given_val;
+</xsl:text>
+ <xsl:text> break;
+</xsl:text>
+ <xsl:text> case "/":
+</xsl:text>
+ <xsl:text> new_val = old_val / given_val;
+</xsl:text>
+ <xsl:text> break;
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> send_blob(delta);
+ <xsl:text> return new_val;
+</xsl:text>
+ <xsl:text>}
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>var current_visible_page;
+</xsl:text>
+ <xsl:text>var current_subscribed_page;
+</xsl:text>
+ <xsl:text>var current_page_index;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>function prepare_svg() {
+</xsl:text>
+ <xsl:text> // prevents context menu from appearing on right click and long touch
+</xsl:text>
+ <xsl:text> document.body.addEventListener('contextmenu', e => {
+</xsl:text>
+ <xsl:text> e.preventDefault();
+</xsl:text>
+ <xsl:text> });
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> for(let eltid in detachable_elements){
+</xsl:text>
+ <xsl:text> let [element,parent] = detachable_elements[eltid];
+</xsl:text>
+ <xsl:text> parent.removeChild(element);
+</xsl:text>
+ <xsl:text> }
</xsl:text>
<xsl:text>};
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text>function send_hmi_value(index, value) {
-</xsl:text>
- <xsl:text> if(index > last_remote_index){
-</xsl:text>
- <xsl:text> updates[index] = value;
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(persistent_indexes.has(index)){
-</xsl:text>
- <xsl:text> let varname = persistent_indexes.get(index);
-</xsl:text>
- <xsl:text> document.cookie = varname+"="+value+"; max-age=3153600000";
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> requestHMIAnimation();
-</xsl:text>
- <xsl:text> return;
+ <xsl:text>function switch_page(page_name, page_index) {
+</xsl:text>
+ <xsl:text> if(current_subscribed_page != current_visible_page){
+</xsl:text>
+ <xsl:text> /* page switch already going */
+</xsl:text>
+ <xsl:text> /* TODO LOG ERROR */
+</xsl:text>
+ <xsl:text> return false;
</xsl:text>
<xsl:text> }
</xsl:text>
<xsl:text>
</xsl:text>
- <xsl:text> let iectype = hmitree_types[index];
-</xsl:text>
- <xsl:text> let tobinary = typedarray_types[iectype];
-</xsl:text>
- <xsl:text> send_blob([
-</xsl:text>
- <xsl:text> new Uint8Array([0]), /* setval = 0 */
-</xsl:text>
- <xsl:text> new Uint32Array([index]),
-</xsl:text>
- <xsl:text> tobinary(value)]);
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> // DON'T DO THAT unless read_iterator in svghmi.c modifies wbuf as well, not only rbuf
-</xsl:text>
- <xsl:text> // cache[index] = value;
-</xsl:text>
- <xsl:text>};
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>function apply_hmi_value(index, new_val) {
-</xsl:text>
- <xsl:text> let old_val = cache[index]
-</xsl:text>
- <xsl:text> if(new_val != undefined && old_val != new_val)
-</xsl:text>
- <xsl:text> send_hmi_value(index, new_val);
-</xsl:text>
- <xsl:text> return new_val;
-</xsl:text>
- <xsl:text>}
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>const quotes = {"'":null, '"':null};
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>function eval_operation_string(old_val, opstr) {
-</xsl:text>
- <xsl:text> let op = opstr[0];
-</xsl:text>
- <xsl:text> let given_val;
-</xsl:text>
- <xsl:text> if(opstr.length < 2)
-</xsl:text>
- <xsl:text> return undefined;
-</xsl:text>
- <xsl:text> if(opstr[1] in quotes){
-</xsl:text>
- <xsl:text> if(opstr.length < 3)
-</xsl:text>
- <xsl:text> return undefined;
-</xsl:text>
- <xsl:text> if(opstr[opstr.length-1] == opstr[1]){
-</xsl:text>
- <xsl:text> given_val = opstr.slice(2,opstr.length-1);
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text> } else {
-</xsl:text>
- <xsl:text> given_val = Number(opstr.slice(1));
+ <xsl:text> if(page_name == undefined)
+</xsl:text>
+ <xsl:text> page_name = current_subscribed_page;
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> let old_desc = page_desc[current_subscribed_page];
+</xsl:text>
+ <xsl:text> let new_desc = page_desc[page_name];
+</xsl:text>
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(new_desc == undefined){
+</xsl:text>
+ <xsl:text> /* TODO LOG ERROR */
+</xsl:text>
+ <xsl:text> return false;
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> let new_val;
-</xsl:text>
- <xsl:text> switch(op){
-</xsl:text>
- <xsl:text> case "=":
-</xsl:text>
- <xsl:text> new_val = given_val;
-</xsl:text>
- <xsl:text> break;
-</xsl:text>
- <xsl:text> case "+":
-</xsl:text>
- <xsl:text> new_val = old_val + given_val;
-</xsl:text>
- <xsl:text> break;
-</xsl:text>
- <xsl:text> case "-":
-</xsl:text>
- <xsl:text> new_val = old_val - given_val;
-</xsl:text>
- <xsl:text> break;
-</xsl:text>
- <xsl:text> case "*":
-</xsl:text>
- <xsl:text> new_val = old_val * given_val;
-</xsl:text>
- <xsl:text> break;
-</xsl:text>
- <xsl:text> case "/":
-</xsl:text>
- <xsl:text> new_val = old_val / given_val;
-</xsl:text>
- <xsl:text> break;
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(page_index == undefined){
+</xsl:text>
+ <xsl:text> page_index = new_desc.page_index;
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text> return new_val;
-</xsl:text>
- <xsl:text>}
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>var current_visible_page;
-</xsl:text>
- <xsl:text>var current_subscribed_page;
-</xsl:text>
- <xsl:text>var current_page_index;
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>function prepare_svg() {
-</xsl:text>
- <xsl:text> // prevents context menu from appearing on right click and long touch
-</xsl:text>
- <xsl:text> document.body.addEventListener('contextmenu', e => {
-</xsl:text>
- <xsl:text> e.preventDefault();
-</xsl:text>
- <xsl:text> });
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> for(let eltid in detachable_elements){
-</xsl:text>
- <xsl:text> let [element,parent] = detachable_elements[eltid];
-</xsl:text>
- <xsl:text> parent.removeChild(element);
+ <xsl:text>
+</xsl:text>
+ <xsl:text> if(old_desc){
+</xsl:text>
+ <xsl:text> old_desc.widgets.map(([widget,relativeness])=>widget.unsub());
</xsl:text>
<xsl:text> }
</xsl:text>
- <xsl:text>};
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>function switch_page(page_name, page_index) {
-</xsl:text>
- <xsl:text> if(current_subscribed_page != current_visible_page){
-</xsl:text>
- <xsl:text> /* page switch already going */
-</xsl:text>
- <xsl:text> /* TODO LOG ERROR */
-</xsl:text>
- <xsl:text> return false;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(page_name == undefined)
-</xsl:text>
- <xsl:text> page_name = current_subscribed_page;
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> let old_desc = page_desc[current_subscribed_page];
-</xsl:text>
- <xsl:text> let new_desc = page_desc[page_name];
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(new_desc == undefined){
-</xsl:text>
- <xsl:text> /* TODO LOG ERROR */
-</xsl:text>
- <xsl:text> return false;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(page_index == undefined){
-</xsl:text>
- <xsl:text> page_index = new_desc.page_index;
-</xsl:text>
- <xsl:text> }
-</xsl:text>
- <xsl:text>
-</xsl:text>
- <xsl:text> if(old_desc){
-</xsl:text>
- <xsl:text> old_desc.widgets.map(([widget,relativeness])=>widget.unsub());
-</xsl:text>
- <xsl:text> }
-</xsl:text>
<xsl:text> const new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
</xsl:text>
<xsl:text>
@@ -7488,8 +7553,6 @@
</xsl:text>
<xsl:text> requestHMIAnimation();
</xsl:text>
- <xsl:text>
-</xsl:text>
<xsl:text> jump_history.push([page_name, page_index]);
</xsl:text>
<xsl:text> if(jump_history.length > 42)