--- a/editors/TextViewer.py Sun Nov 20 18:36:13 2022 +0100
+++ b/editors/TextViewer.py Wed Nov 23 14:18:25 2022 +0100
@@ -130,8 +130,7 @@
self.Editor.SetUseTabs(0)
self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT |
- wx.stc.STC_MOD_BEFOREDELETE |
- wx.stc.STC_PERFORMED_USER)
+ wx.stc.STC_MOD_BEFOREDELETE) self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, self.Editor)
self.Editor.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
@@ -221,25 +220,24 @@
self.SearchResults = None
self.CurrentFindHighlight = None
def OnModification(self, event):
if not self.DisableEvents:
mod_type = event.GetModificationType()
if mod_type & wx.stc.STC_MOD_BEFOREINSERT:
if self.CurrentAction is None:
+ self.Buffering = "ShouldStart" elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1:
- self.Controler.EndBuffering()
+ self.Buffering = "ShouldRestart" self.CurrentAction = ("Add", event.GetPosition())
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter() elif mod_type & wx.stc.STC_MOD_BEFOREDELETE:
if self.CurrentAction is None:
+ self.Buffering = "ShouldStart" elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1:
- self.Controler.EndBuffering()
+ self.Buffering = "ShouldRestart" self.CurrentAction = ("Delete", event.GetPosition())
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter() def OnDoDrop(self, event):
@@ -387,7 +385,7 @@
elif values[3] == self.TagName:
event.SetDragText(values[0])
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter() message = _("Variable don't belong to this POU!")
@@ -437,10 +435,14 @@
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
+ def EndBuffering(self): + self.Controler.EndBuffering() if self.CurrentAction is not None:
- self.Controler.EndBuffering()
self.CurrentAction = None
+ self.Buffering == "Off" def GetBufferState(self):
if not self.Debug and self.TextSyntax != "ALL":
@@ -840,12 +842,29 @@
self.RemoveHighlight(*self.CurrentFindHighlight)
self.CurrentFindHighlight = None
+ pending_model_refresh=False + self.pending_model_refresh=False + if self.Buffering == "ShouldStart": + elif self.Buffering == "ShouldRestart": self.Controler.SetEditedElementText(self.TagName, self.GetText())
self.ResetSearchResults()
+ def RefreshModelAfter(self): + if self.pending_model_refresh: + self.pending_model_refresh=True + wx.CallAfter(self.RefreshModel) def OnKeyDown(self, event):
if self.Controler is not None:
--- a/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Sun Nov 20 18:36:13 2022 +0100
+++ b/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Wed Nov 23 14:18:25 2022 +0100
@@ -25,7 +25,7 @@
<dc:format>image/svg+xml</dc:format>
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
@@ -40,17 +40,17 @@
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1850" + inkscape:window-height="1036" - inkscape:zoom="0.23177389"
- inkscape:cx="1999.5317"
- inkscape:cy="-682.74047"
+ inkscape:zoom="0.46354778" + inkscape:cx="-544.27948" + inkscape:cy="655.56978" inkscape:window-maximized="1"
- inkscape:current-layer="hmi0"
+ inkscape:current-layer="g2496" inkscape:guide-bbox="true"
@@ -67,7 +67,7 @@
transform="translate(1320,1520)"
- inkscape:label="HMI:Page:RelativePage@/FB_ZERO" />
+ inkscape:label="HMI:Page:RelativePage:p=6@p=page_number@/FB_ZERO" /> sodipodi:insensitive="true"
@@ -77,7 +77,7 @@
transform="translate(2640,759.99998)"
- inkscape:label="HMI:Page:Relative" />
+ inkscape:label="HMI:Page:Relative:p=5@p=page_number" /> @@ -86,10 +86,10 @@
transform="translate(3940,-2.1367187e-5)"
- inkscape:label="HMI:Page:Conditional"
+ inkscape:label="HMI:Page:Conditional:p=4@p=page_number" sodipodi:insensitive="true" />
- inkscape:label="HMI:Page:Unconditional"
+ inkscape:label="HMI:Page:Unconditional:p=3@p=page_number" transform="translate(2640,-2.1367187e-5)"
@@ -99,7 +99,7 @@
sodipodi:insensitive="true" />
- inkscape:label="HMI:Page:AbsolutePage"
+ inkscape:label="HMI:Page:AbsolutePage:p=2@p=page_number" transform="translate(1320,759.99998)"
@@ -116,7 +116,7 @@
transform="translate(1320,-2.1367187e-5)"
- inkscape:label="HMI:Page:Home"
+ inkscape:label="HMI:Page:Home:p=1@p=page_number" sodipodi:insensitive="true" />
@@ -621,6 +621,18 @@
y="598.98303">HMI:Jump:RelativePage</tspan></text>
+ inkscape:label="HMI:Display@page_number" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.03883362px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="stroke-width:1px">0</tspan></text> @@ -1200,7 +1212,7 @@
inkscape:label="MYNODE:+1"
- transform="matrix(1.3729714,0,0,1.3729714,-299.47126,-800.64485)"
+ transform="matrix(1.3729714,0,0,1.3729714,-359.47134,-800.64485)" style="stroke-width:0.7283473">
@@ -1226,7 +1238,7 @@
inkscape:label="MYNODE:3"
- transform="translate(665.54481,-11.353461)">
+ transform="translate(620.54487,-11.353461)"> transform="translate(1466.6549,2099.2529)"
inkscape:label="HMI:Jump:RelativePage@/FB_TWO@enable=/FB_TWO/SOME_BOOL#enable"
@@ -1286,7 +1298,7 @@
- transform="translate(342.39289,-11.353461)"
+ transform="translate(312.39295,-11.353461)" inkscape:label="MYNODE:2">
@@ -1350,7 +1362,7 @@
inkscape:label="MYNODE:1"
- transform="translate(19.240974,-11.353461)">
+ transform="translate(4.2410198,-11.353461)"> transform="translate(1466.6549,2099.2529)"
inkscape:label="HMI:Jump:RelativePage@/FB_ZERO@enable=/FB_ZERO/SOME_BOOL#enable"
@@ -1815,4 +1827,23 @@
id="tspan2966">- Press Ctrl+X to edit SVG elements directly with XML editor</tspan></text>
+ transform="translate(-4020,2.1367187e-5)" + inkscape:label="HMI:VarInit:0@page_number" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + sodipodi:role="line">declaration of user_level HMI local variable</tspan><tspan + sodipodi:role="line">(not a PLC variable)</tspan></text> --- a/svghmi/detachable_pages.ysl2 Sun Nov 20 18:36:13 2022 +0100
+++ b/svghmi/detachable_pages.ysl2 Wed Nov 23 14:18:25 2022 +0100
@@ -137,6 +137,10 @@
const "_detachable_elements", "func:detachable_elements($hmi_pages | $keypads)";
const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
+emit "declarations:page-class" { + | class PageWidget extends Widget{} emit "declarations:detachable-elements" {
| var detachable_elements = {
@@ -165,8 +169,13 @@
const "all_page_widgets","$hmi_widgets[@id = $page_all_elements/@id and @id != $page/@id]";
const "page_managed_widgets","$all_page_widgets[not(@id=$in_forEach_widget_ids)]";
+ const "page_root_path", "$desc/path[not(@assign)]"; + if "count($page_root_path)>1" + error > Page id="«$page/@id»" : only one root path can be declared const "page_relative_widgets",
- "$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]";
+ "$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $page_root_path/@value)]"; // Take closest ancestor in detachable_elements
// since nested detachable elements are filtered out
@@ -178,19 +187,19 @@
ancestor-or-self::*[@id = $detachable_elements/@id]""";
- //| widget: hmi_widgets["«@id»"],
| bbox: [«$p/@x», «$p/@y», «$p/@w», «$p/@h»],
- if "$desc/path/@value" {
- if "count($desc/path/@index)=0"
- warning > Page id="«$page/@id»" : No match for path "«$desc/path/@value»" in HMI tree
- | page_index: «$desc/path/@index»,
- | page_class: "«$indexed_hmitree/*[@hmipath = $desc/path/@value]/@class»",
+ if "count($page_root_path)=1"{ + if "count($page_root_path/@index)=0" + warning > Page id="«$page/@id»" : No match for path "«$page_root_path/@value»" in HMI tree + | page_index: «$page_root_path/@index», + | page_class: "«$indexed_hmitree/*[@hmipath = $page_root_path/@value]/@class»", + | [hmi_widgets["«$page/@id»"], []], foreach "$page_managed_widgets" {
const "widget_paths_relativeness"
foreach "func:widget(@id)/path" {
- value "func:is_descendant_path(@value, $desc/path/@value)";
+ value "func:is_descendant_path(@value, $page_root_path/@value)"; if "position()!=last()" > ,
| [hmi_widgets["«@id»"], [«$widget_paths_relativeness»]]`if "position()!=last()" > ,`
--- a/svghmi/gen_index_xhtml.xslt Sun Nov 20 18:36:13 2022 +0100
+++ b/svghmi/gen_index_xhtml.xslt Wed Nov 23 14:18:25 2022 +0100
@@ -734,6 +734,21 @@
<xsl:variable name="_detachable_elements" select="func:detachable_elements($hmi_pages | $keypads)"/>
<xsl:variable name="detachable_elements" select="$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]"/>
+ <declarations:page-class/> + <xsl:template match="declarations:page-class"> + <xsl:text>/* </xsl:text> + <xsl:value-of select="local-name()"/> + <xsl:text>class PageWidget extends Widget{} <declarations:detachable-elements/>
<xsl:template match="declarations:detachable-elements">
@@ -787,7 +802,15 @@
<xsl:variable name="page_all_elements" select="func:all_related_elements($page)"/>
<xsl:variable name="all_page_widgets" select="$hmi_widgets[@id = $page_all_elements/@id and @id != $page/@id]"/>
<xsl:variable name="page_managed_widgets" select="$all_page_widgets[not(@id=$in_forEach_widget_ids)]"/>
- <xsl:variable name="page_relative_widgets" select="$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]"/>
+ <xsl:variable name="page_root_path" select="$desc/path[not(@assign)]"/> + <xsl:if test="count($page_root_path)>1"> + <xsl:message terminate="yes"> + <xsl:text>Page id="</xsl:text> + <xsl:value-of select="$page/@id"/> + <xsl:text>" : only one root path can be declared</xsl:text> + <xsl:variable name="page_relative_widgets" select="$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $page_root_path/@value)]"/> <xsl:variable name="sumarized_page" select="func:sumarized_elements($page_all_elements)"/>
<xsl:variable name="required_detachables" select="$sumarized_page/ ancestor-or-self::*[@id = $detachable_elements/@id]"/>
@@ -804,31 +827,35 @@
<xsl:value-of select="$p/@h"/>
- <xsl:if test="$desc/path/@value">
- <xsl:if test="count($desc/path/@index)=0">
+ <xsl:if test="count($page_root_path)=1"> + <xsl:if test="count($page_root_path/@index)=0"> <xsl:message terminate="no">
<xsl:text>Page id="</xsl:text>
<xsl:value-of select="$page/@id"/>
<xsl:text>" : No match for path "</xsl:text>
- <xsl:value-of select="$desc/path/@value"/>
+ <xsl:value-of select="$page_root_path/@value"/> <xsl:text>" in HMI tree</xsl:text>
<xsl:text> page_index: </xsl:text>
- <xsl:value-of select="$desc/path/@index"/>
+ <xsl:value-of select="$page_root_path/@index"/> <xsl:text> page_class: "</xsl:text>
- <xsl:value-of select="$indexed_hmitree/*[@hmipath = $desc/path/@value]/@class"/>
+ <xsl:value-of select="$indexed_hmitree/*[@hmipath = $page_root_path/@value]/@class"/> + <xsl:text> [hmi_widgets["</xsl:text> + <xsl:value-of select="$page/@id"/> <xsl:for-each select="$page_managed_widgets">
<xsl:variable name="widget_paths_relativeness">
<xsl:for-each select="func:widget(@id)/path">
- <xsl:value-of select="func:is_descendant_path(@value, $desc/path/@value)"/>
+ <xsl:value-of select="func:is_descendant_path(@value, $page_root_path/@value)"/> <xsl:if test="position()!=last()">
@@ -1440,7 +1467,7 @@
<xsl:if test="$widget/@enable_expr">
- <xsl:text> assignments: [],
+ <xsl:text> enable_assignments: [], <xsl:text> compute_enable: function(value, oldval, varnum) {
@@ -1456,13 +1483,13 @@
<xsl:if test="$varid = generate-id()">
<xsl:text> if(varnum == </xsl:text>
<xsl:value-of select="$varnum"/>
- <xsl:text>) this.assignments[</xsl:text>
+ <xsl:text>) this.enable_assignments[</xsl:text> <xsl:value-of select="position()-1"/>
<xsl:text> let </xsl:text>
<xsl:value-of select="@assign"/>
- <xsl:text> = this.assignments[</xsl:text>
+ <xsl:text> = this.enable_assignments[</xsl:text> <xsl:value-of select="position()-1"/>
@@ -2388,7 +2415,9 @@
<xsl:variable name="included_ids" select="$parsed_widgets/widget[not(@type = $excluded_types) and not(@id = $discardable_elements/@id)]/@id"/>
+ <xsl:variable name="page_ids" select="$parsed_widgets/widget[@type = 'Page']/@id"/> <xsl:variable name="hmi_widgets" select="$hmi_elements[@id = $included_ids]"/>
+ <xsl:variable name="page_widgets" select="$hmi_elements[@id = $page_ids]"/> <xsl:variable name="result_widgets" select="$result_svg_ns//*[@id = $hmi_widgets/@id]"/>
<declarations:hmi-elements/>
<xsl:template match="declarations:hmi-elements">
@@ -2402,7 +2431,7 @@
<xsl:text>var hmi_widgets = {
- <xsl:apply-templates mode="hmi_widgets" select="$hmi_widgets"/>
+ <xsl:apply-templates mode="hmi_widgets" select="$hmi_widgets | $page_widgets"/> @@ -6367,10 +6396,10 @@
<xsl:variable name="target_page_path">
- <xsl:value-of select="$hmi_pages_descs[arg[1]/@value = $target_page_name]/path[1]/@value"/>
+ <xsl:value-of select="$hmi_pages_descs[arg[1]/@value = $target_page_name]/path[not(@assign)]/@value"/> - <xsl:value-of select="$page_desc/path[1]/@value"/>
+ <xsl:value-of select="$page_desc/path[not(@assign)]/@value"/> @@ -7195,6 +7224,128 @@
+ <xsl:template match="widget[@type='Page']" mode="widget_desc"> + <xsl:value-of select="@type"/> + <xsl:text>Arguments are either: + <xsl:text>- XXX reference path TODO + <xsl:text>- name=value: setting variable with literal value. + <xsl:text>- name=other_name: copy variable content into another + <xsl:text>"active"+"inactive" labeled elements can be provided to show feedback when pressed + <xsl:text>HMI:Page:notify=1@notify=/PLCVAR + <xsl:text>HMI:Page:ack=2:notify=1@ack=.local_var@notify=/PLCVAR + <xsl:text>Page </xsl:text> + <xsl:template match="widget[@type='Page']" mode="widget_defs"> + <xsl:param name="hmi_element"/> + <xsl:variable name="disability"> + <xsl:call-template name="defs_by_labels"> + <xsl:with-param name="hmi_element" select="$hmi_element"/> + <xsl:with-param name="labels"> + <xsl:text>/disabled</xsl:text> + <xsl:with-param name="mandatory" select="'no'"/> + <xsl:value-of select="$disability"/> + <xsl:variable name="has_disability" select="string-length($disability)>0"/> + <xsl:text> assignments: {}, + <xsl:text> dispatch: function(value, oldval, varnum) { + <xsl:variable name="widget" select="."/> + <xsl:for-each select="path"> + <xsl:variable name="varid" select="generate-id()"/> + <xsl:variable name="varnum" select="position()-1"/> + <xsl:if test="@assign"> + <xsl:for-each select="$widget/path[@assign]"> + <xsl:if test="$varid = generate-id()"> + <xsl:text> if(varnum == </xsl:text> + <xsl:value-of select="$varnum"/> + <xsl:text>) this.assignments["</xsl:text> + <xsl:value-of select="@assign"/> + <xsl:text> assign: function() { + <xsl:variable name="paths" select="path"/> + <xsl:for-each select="arg[contains(@value,'=')]"> + <xsl:variable name="name" select="substring-before(@value,'=')"/> + <xsl:variable name="value" select="substring-after(@value,'=')"/> + <xsl:variable name="index"> + <xsl:for-each select="$paths"> + <xsl:if test="@assign = $name"> + <xsl:value-of select="position()-1"/> + <xsl:variable name="isVarName" select="regexp:test($value,'^[a-zA-Z_][a-zA-Z0-9_]+$')"/> + <xsl:when test="$isVarName"> + <xsl:text> const </xsl:text> + <xsl:value-of select="$value"/> + <xsl:text> = this.assignments["</xsl:text> + <xsl:value-of select="$value"/> + <xsl:text> if(</xsl:text> + <xsl:value-of select="$value"/> + <xsl:text> != undefined) + <xsl:text> this.apply_hmi_value(</xsl:text> + <xsl:value-of select="$index"/> + <xsl:text>, </xsl:text> + <xsl:value-of select="$value"/> + <xsl:text> this.apply_hmi_value(</xsl:text> + <xsl:value-of select="$index"/> + <xsl:text>, </xsl:text> + <xsl:value-of select="$value"/> <xsl:template match="widget[@type='PathSlider']" mode="widget_desc">
<xsl:value-of select="@type"/>
@@ -12128,29 +12279,37 @@
- <xsl:text>var screensaver_timer = null;
- <xsl:text>function reset_screensaver_timer() {
- <xsl:text> if(screensaver_timer){
- <xsl:text> window.clearTimeout(screensaver_timer);
+ <xsl:text>if(screensaver_delay){ + <xsl:text> var screensaver_timer = null; + <xsl:text> function reset_screensaver_timer() { + <xsl:text> if(screensaver_timer){ + <xsl:text> window.clearTimeout(screensaver_timer); + <xsl:text> screensaver_timer = window.setTimeout(() => { + <xsl:text> switch_page("ScreenSaver"); + <xsl:text> screensaver_timer = null; + <xsl:text> }, screensaver_delay*1000); - <xsl:text> screensaver_timer = window.setTimeout(() => {
- <xsl:text> switch_page("ScreenSaver");
- <xsl:text> screensaver_timer = null;
- <xsl:text> }, screensaver_delay*1000);
+ <xsl:text> document.body.addEventListener('pointerdown', reset_screensaver_timer); + <xsl:text> // initialize screensaver + <xsl:text> reset_screensaver_timer(); - <xsl:text>if(screensaver_delay)
- <xsl:text> document.body.addEventListener('pointerdown', reset_screensaver_timer);
@@ -12314,6 +12473,12 @@
+ <xsl:text> // when entering a page, assignments are evaluated + <xsl:text> new_desc.widgets[0][0].assign(); @@ -12474,16 +12639,12 @@
- <xsl:text>// initialize screensaver
- <xsl:text>reset_screensaver_timer();
<xsl:text>var reconnect_delay = 0;
<xsl:text>var periodic_reconnect_timer;
+ <xsl:text>var force_reconnect = false; <xsl:text>// Once connection established
@@ -12504,6 +12665,8 @@
<xsl:text> periodic_reconnect_timer = window.setTimeout(() => {
+ <xsl:text> force_reconnect = true; <xsl:text> periodic_reconnect_timer = null;
@@ -12540,14 +12703,26 @@
- <xsl:text> // TODO : add visible notification while waiting for reload
+ <xsl:text> // Do not attempt to reconnect immediately in case: + <xsl:text> // - connection was closed by server (PLC stop) + <xsl:text> // - connection was closed locally with an intention to reconnect + <xsl:text> if(evt.code=1000 && !force_reconnect){ + <xsl:text> window.alert("Connection closed by server"); + <xsl:text> location.reload(); <xsl:text> window.setTimeout(create_ws, reconnect_delay);
<xsl:text> reconnect_delay += 500;
+ <xsl:text> force_reconnect = false; --- a/svghmi/svghmi.js Sun Nov 20 18:36:13 2022 +0100
+++ b/svghmi/svghmi.js Wed Nov 23 14:18:25 2022 +0100
@@ -525,6 +525,9 @@
: page_name + "@" + hmitree_paths[page_index]);
+ // when entering a page, assignments are evaluated + new_desc.widgets[0][0].assign(); @@ -607,6 +610,7 @@
var periodic_reconnect_timer;
+var force_reconnect = false; // Once connection established
function ws_onopen(evt) {
@@ -617,6 +621,7 @@
window.clearTimeout(periodic_reconnect_timer);
periodic_reconnect_timer = window.setTimeout(() => {
+ force_reconnect = true; periodic_reconnect_timer = null;
@@ -635,10 +640,16 @@
function ws_onclose(evt) {
console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in "+reconnect_delay+"ms.");
- // TODO : add visible notification while waiting for reload
+ // Do not attempt to reconnect immediately in case: + // - connection was closed by server (PLC stop) + // - connection was closed locally with an intention to reconnect + if(evt.code=1000 && !force_reconnect){ + window.alert("Connection closed by server"); window.setTimeout(create_ws, reconnect_delay);
+ force_reconnect = false; --- a/svghmi/widgets_common.ysl2 Sun Nov 20 18:36:13 2022 +0100
+++ b/svghmi/widgets_common.ysl2 Wed Nov 23 14:18:25 2022 +0100
@@ -134,7 +134,7 @@
| "«@id»": new «$widget/@type»Widget ("«@id»",«$freq»,[«$args»],[«$variables»],«$enable_expr»,{
if "$widget/@enable_expr" {
+ | enable_assignments: [], | compute_enable: function(value, oldval, varnum) {
@@ -142,8 +142,8 @@
const "varid","generate-id()";
const "varnum","position()-1";
if "@assign" foreach "$widget/path[@assign]" if "$varid = generate-id()" {
- | if(varnum == «$varnum») this.assignments[«position()-1»] = value;
- | let «@assign» = this.assignments[«position()-1»];
+ | if(varnum == «$varnum») this.enable_assignments[«position()-1»] = value; + | let «@assign» = this.enable_assignments[«position()-1»]; | if(«@assign» == undefined) break;
@@ -600,12 +600,14 @@
const "included_ids","$parsed_widgets/widget[not(@type = $excluded_types) and not(@id = $discardable_elements/@id)]/@id";
+const "page_ids","$parsed_widgets/widget[@type = 'Page']/@id"; const "hmi_widgets","$hmi_elements[@id = $included_ids]";
+const "page_widgets","$hmi_elements[@id = $page_ids]"; const "result_widgets","$result_svg_ns//*[@id = $hmi_widgets/@id]";
emit "declarations:hmi-elements" {
- apply "$hmi_widgets", mode="hmi_widgets";
+ apply "$hmi_widgets | $page_widgets", mode="hmi_widgets";