// widgets_common.ysl2 in xsl decl labels(*ptr, name="defs_by_labels") alias call-template { with "hmi_element", "$hmi_element"; with "labels"{text *ptr}; content; }; decl optional_labels(*ptr) alias - { /* TODO add some per label xslt variable to check if exist */ labels(*ptr){ with "mandatory","'no'"; content; } }; decl activable_labels(*ptr) alias - { optional_labels(*ptr) { with "subelements","'active inactive'"; content; } }; template "svg:*", mode="hmi_widgets" { const "widget", "func:widget(@id)"; const "eltid","@id"; const "args" foreach "$widget/arg" > "«@value»"`if "position()!=last()" > ,` const "indexes" foreach "$widget/path" { choose { when "not(@index)" { warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree } otherwise { > «@index»`if "position()!=last()" > ,` } } } | "«@id»": new «$widget/@type»Widget ("«@id»",[«$args»],[«$indexes»],{ apply "$widget", mode="widget_defs" with "hmi_element","."; | })`if "position()!=last()" > ,` } def "func:unique_types" { param "elts_with_type"; choose { when "count($elts_with_type) > 1" { const "prior_results","func:unique_types($elts_with_type[position()!=last()])"; choose { when "$elts_with_type[last()][@type = $prior_results/@type]"{ // type already in result "$prior_results"; } otherwise { result "$prior_results | $elts_with_type[last()]"; } } } otherwise { result "$elts_with_type"; } } } emit "preamble:widget-base-class" { || class Widget { offset = 0; frequency = 10; /* FIXME arbitrary default max freq. Obtain from config ? */ unsubscribable = false; constructor(elt_id,args,indexes,members){ this.element_id = elt_id; this.element = id(elt_id); this.args = args; this.indexes = indexes; Object.keys(members).forEach(prop => this[prop]=members[prop]); } unsub(){ /* remove subsribers */ if(!this.unsubscribable) for(let index of this.indexes){ let idx = index + this.offset; subscribers[idx].delete(this); } this.offset = 0; } sub(new_offset=0){ /* set the offset because relative */ this.offset = new_offset; /* add this's subsribers */ if(!this.unsubscribable) for(let index of this.indexes){ subscribers[index + new_offset].add(this); } need_cache_apply.push(this); } apply_cache() { if(!this.unsubscribable) for(let index of this.indexes){ /* dispatch current cache in newly opened page widgets */ let realindex = index+this.offset; let cached_val = cache[realindex]; if(cached_val != undefined) dispatch_value_to_widget(this, realindex, cached_val, cached_val); } } get_idx(index) { let orig = this.indexes[index]; return this.offset ? orig + this.offset : orig; } } || } emit "preamble:hmi-classes" { const "used_widget_types", "func:unique_types($parsed_widgets/widget)"; apply "$used_widget_types", mode="widget_class"; } template "widget", mode="widget_class" || class «@type»Widget extends Widget{ /* empty class, as «@type» widget didn't provide any */ } || const "excluded_types", "str:split('Page Lang')"; const "excluded_ids","$parsed_widgets/widget[not(@type = $excluded_types)]/@id"; emit "preamble:hmi-elements" { | var hmi_widgets = { apply "$hmi_elements[@id = $excluded_ids]", mode="hmi_widgets"; | } } function "defs_by_labels" { param "labels","''"; param "mandatory","'yes'"; param "subelements","/.."; param "hmi_element"; const "widget_type","@type"; foreach "str:split($labels)" { const "name","."; const "elt","$result_svg_ns//*[@id = $hmi_element/@id]//*[@inkscape:label=$name][1]"; choose { when "not($elt/@id)" { if "$mandatory='yes'" { error > «$widget_type» widget must have a «$name» element } // otherwise produce nothing } otherwise { | «$name»_elt: id("«$elt/@id»"), if "$subelements" { | «$name»_sub: { foreach "str:split($subelements)" { const "subname","."; const "subelt","$elt/*[@inkscape:label=$subname][1]"; choose { when "not($subelt/@id)" { if "$mandatory='yes'" { error > «$widget_type» widget must have a «$name»/«$subname» element } | /* missing «$name»/«$subname» element */ } otherwise { | "«$subname»": id("«$subelt/@id»")`if "position()!=last()" > ,` } } } | }, } } } } } def "func:escape_quotes" { param "txt"; // have to use a python string to enter escaped quote const "frst", !"substring-before($txt,'\"')"!; const "frstln", "string-length($frst)"; choose { when "$frstln > 0 and string-length($txt) > $frstln" { result !"concat($frst,'\\\"',func:escape_quotes(substring-after($txt,'\"')))"!; } otherwise { result "$txt"; } } }