--- a/svghmi/gen_index_xhtml.xslt Tue Feb 09 07:41:24 2021 +0100
+++ b/svghmi/gen_index_xhtml.xslt Tue Feb 09 07:46:02 2021 +0100
@@ -192,12 +192,12 @@
- <xsl:when test="regexp:test($path,'^\.[a-zA-Z0-9_]+')">
+ <xsl:when test="regexp:test($path,'^\.[a-zA-Z0-9_]+$')"> <xsl:attribute name="type">
<xsl:text>PAGE_LOCAL</xsl:text>
- <xsl:when test="regexp:test($path,'^[a-zA-Z0-9_]+')">
+ <xsl:when test="regexp:test($path,'^[a-zA-Z0-9_]+$')"> <xsl:attribute name="type">
<xsl:text>HMI_LOCAL</xsl:text>
@@ -233,6 +233,10 @@
<xsl:variable name="_parsed_widgets">
+ <widget type="VarInitPersistent"> <xsl:apply-templates mode="parselabel" select="$hmi_elements"/>
<xsl:variable name="parsed_widgets" select="exsl:node-set($_parsed_widgets)"/>
@@ -972,7 +976,9 @@
<xsl:variable name="translations" select="ns:GetTranslations($translatable_strings)"/>
<xsl:text>var langs = [</xsl:text>
<xsl:for-each select="$translations/langs/lang">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
@@ -983,9 +989,18 @@
<xsl:for-each select="$translatable_texts">
<xsl:variable name="n" select="position()"/>
- <xsl:text> ["</xsl:text>
- <xsl:value-of select="@id"/>
- <xsl:text>",[</xsl:text>
+ <xsl:variable name="current_id" select="@id"/> + <xsl:variable name="text_unlinked_uses" select="$result_svg_ns//svg:text[@original = $current_id]/@id"/> + <xsl:text> [[</xsl:text> + <xsl:for-each select="@id | $text_unlinked_uses"> + <xsl:text>id("</xsl:text> + <xsl:value-of select="."/> + <xsl:text>")</xsl:text> + <xsl:if test="position()!=last()"> + <xsl:text>],[</xsl:text> <xsl:for-each select="$translations/messages/msgid[$n]/msg">
<xsl:for-each select="line">
@@ -1126,11 +1141,13 @@
<xsl:text>var next_available_index = hmitree_types.length;
+ <xsl:text>let cookies = new Map(document.cookie.split("; ").map(s=>s.split("="))); <xsl:text>const local_defaults = {
- <xsl:for-each select="$parsed_widgets/widget[@type = 'VarInit']">
+ <xsl:for-each select="$parsed_widgets/widget[starts-with(@type,'VarInit')]"> <xsl:if test="count(path) != 1">
<xsl:message terminate="yes">
<xsl:text>VarInit </xsl:text>
@@ -1145,17 +1162,47 @@
<xsl:text> only applies to HMI variable.</xsl:text>
+ <xsl:text> "</xsl:text> <xsl:value-of select="path/@value"/>
- <xsl:value-of select="arg[1]/@value"/>
+ <xsl:when test="@type = 'VarInitPersistent'"> + <xsl:text>cookies.has("</xsl:text> + <xsl:value-of select="path/@value"/> + <xsl:text>")?cookies.get("</xsl:text> + <xsl:value-of select="path/@value"/> + <xsl:text>"):</xsl:text> + <xsl:value-of select="arg[1]/@value"/> + <xsl:value-of select="arg[1]/@value"/> + <xsl:if test="position()!=last()"> + <xsl:text>const persistent_locals = new Set([ + <xsl:for-each select="$parsed_widgets/widget[@type='VarInitPersistent']"> + <xsl:text> "</xsl:text> + <xsl:value-of select="path/@value"/> <xsl:if test="position()!=last()">
+ <xsl:text>var persistent_indexes = new Map(); <xsl:text>var cache = hmitree_types.map(_ignored => undefined);
@@ -1193,10 +1240,16 @@
<xsl:text> let defaultval = local_defaults[varname];
- <xsl:text> if(defaultval != undefined)
+ <xsl:text> if(defaultval != undefined) { <xsl:text> cache[new_index] = defaultval;
+ <xsl:text> if(persistent_locals.has(varname)) + <xsl:text> persistent_indexes.set(new_index, varname); <xsl:text> return new_index;
@@ -1506,12 +1559,32 @@
+ <xsl:text> activate_activable(eltsub) { + <xsl:text> eltsub.inactive.style.display = "none"; + <xsl:text> eltsub.active.style.display = ""; + <xsl:text> inactivate_activable(eltsub) { + <xsl:text> eltsub.active.style.display = "none"; + <xsl:text> eltsub.inactive.style.display = ""; - <xsl:variable name="excluded_types" select="str:split('Page VarInit')"/>
+ <xsl:variable name="excluded_types" select="str:split('Page VarInit VarInitPersistent')"/> <xsl:key name="TypesKey" match="widget" use="@type"/>
<declarations:hmi-classes/>
<xsl:template match="declarations:hmi-classes">
@@ -3825,6 +3898,8 @@
<xsl:text> highlight_selection(){
+ <xsl:text> if(this.last_selection == undefined) return; <xsl:text> let highlighted_row = this.last_selection - this.menu_offset;
<xsl:text> if(highlighted_row < 0) return;
@@ -5123,7 +5198,7 @@
<xsl:text> this._shift = this.shift;
- <xsl:text> (this.shift?widget_active_activable:widget_inactive_activable)(this.Shift_sub);
+ <xsl:text> (this.shift?this.activate_activable:this.inactivate_activable)(this.Shift_sub); @@ -5131,7 +5206,7 @@
<xsl:text> this._caps = this.caps;
- <xsl:text> (this.caps?widget_active_activable:widget_inactive_activable)(this.CapsLock_sub);
+ <xsl:text> (this.caps?this.activate_activable:this.inactivate_activable)(this.CapsLock_sub); @@ -6734,6 +6809,72 @@
+ <xsl:text>var translated = false; + <xsl:text>function switch_langnum(langnum) { + <xsl:text> if(langnum == current_lang) { + <xsl:text> if (!translated) { + <xsl:text> translated = true; + <xsl:text> for (let translation of translations) { + <xsl:text> let [objs] = translation; + <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> let [objs, msgs, orig] = translation; + <xsl:text> let msg = langnum == 0 ? orig : msgs[langnum - 1]; + <xsl:text> for (let obj of objs) { + <xsl:text> msg.split('\n').map((line,i) => {obj.children[i].textContent = line;}); + <xsl:text> current_lang = langnum; + <xsl:text>var lang_local_index = hmi_local_index("lang"); + <xsl:text>subscribers(lang_local_index).add({ + <xsl:text> indexes: [lang_local_index], + <xsl:text> new_hmi_value: function(index, value, oldval) { + <xsl:text> switch_langnum(value); + <xsl:text>var current_lang = 0; + <xsl:text>switch_langnum(cache[lang_local_index]); <xsl:text>function update_subscriptions() {
@@ -6812,6 +6953,22 @@
<xsl:text> updates[index] = value;
+ <xsl:text> if(persistent_indexes.has(index)){ + <xsl:text> let varname = persistent_indexes.get(index); + <xsl:text> console.log(varname+"="+value+"; max-age=3153600000"); + <xsl:text> document.cookie = varname+"="+value+"; max-age=3153600000"; <xsl:text> requestHMIAnimation();
@@ -6930,28 +7087,6 @@
- <xsl:text>function change_hmi_value(index, opstr) {
- <xsl:text> let old_val = cache[index];
- <xsl:text> let new_val = eval_operation_string(old_val, opstr);
- <xsl:text> if(new_val != undefined && old_val != new_val)
- <xsl:text> send_hmi_value(index, new_val);
- <xsl:text> // TODO else raise
- <xsl:text> return new_val;
<xsl:text>var current_visible_page;
<xsl:text>var current_subscribed_page;
@@ -7256,34 +7391,6 @@
- <xsl:text>function widget_active_activable(eltsub) {
- <xsl:text> if(eltsub.inactive_style === undefined)
- <xsl:text> eltsub.inactive_style = eltsub.inactive.getAttribute("style");
- <xsl:text> eltsub.inactive.setAttribute("style", "display:none");
- <xsl:text> if(eltsub.active_style !== undefined)
- <xsl:text> eltsub.active.setAttribute("style", eltsub.active_style);
- <xsl:text>function widget_inactive_activable(eltsub) {
- <xsl:text> if(eltsub.active_style === undefined)
- <xsl:text> eltsub.active_style = eltsub.active.getAttribute("style");
- <xsl:text> eltsub.active.setAttribute("style", "display:none");
- <xsl:text> if(eltsub.inactive_style !== undefined)
- <xsl:text> eltsub.inactive.setAttribute("style", eltsub.inactive_style);
--- a/svghmi/svghmi.js Tue Feb 09 07:41:24 2021 +0100
+++ b/svghmi/svghmi.js Tue Feb 09 07:46:02 2021 +0100
@@ -243,6 +243,13 @@
function send_hmi_value(index, value) {
if(index > last_remote_index){
+ if(persistent_indexes.has(index)){ + let varname = persistent_indexes.get(index); + console.log(varname+"="+value+"; max-age=3153600000"); + document.cookie = varname+"="+value+"; max-age=3153600000"; --- a/svghmi/widgets_common.ysl2 Tue Feb 09 07:41:24 2021 +0100
+++ b/svghmi/widgets_common.ysl2 Tue Feb 09 07:46:02 2021 +0100
@@ -68,16 +68,32 @@
var last_remote_index = hmitree_types.length - 1;
var next_available_index = hmitree_types.length;
+ let cookies = new Map(document.cookie.split("; ").map(s=>s.split("="))); - foreach "$parsed_widgets/widget[@type = 'VarInit']"{
+ foreach "$parsed_widgets/widget[starts-with(@type,'VarInit')]"{ if "count(path) != 1" error > VarInit «@id» must have only one variable given.
if "path/@type != 'PAGE_LOCAL' and path/@type != 'HMI_LOCAL'" error > VarInit «@id» only applies to HMI variable.
- | "«path/@value»":«arg[1]/@value»`if "position()!=last()" > ,`
+ when "@type = 'VarInitPersistent'" > cookies.has("«path/@value»")?cookies.get("«path/@value»"):«arg[1]/@value» + otherwise > «arg[1]/@value» + if "position()!=last()" > , + const persistent_locals = new Set([ + foreach "$parsed_widgets/widget[@type='VarInitPersistent']"{ + | "«path/@value»"`if "position()!=last()" > ,` + var persistent_indexes = new Map(); var cache = hmitree_types.map(_ignored => undefined);
function page_local_index(varname, pagename){
@@ -96,8 +112,11 @@
pagevars[varname] = new_index;
let defaultval = local_defaults[varname];
- if(defaultval != undefined)
+ if(defaultval != undefined) { cache[new_index] = defaultval;
+ if(persistent_locals.has(varname)) + persistent_indexes.set(new_index, varname); @@ -265,7 +284,7 @@
-const "excluded_types", "str:split('Page VarInit')";
+const "excluded_types", "str:split('Page VarInit VarInitPersistent')"; // Key to filter unique types
key "TypesKey", "widget", "@type";