Example #1
0
    def unSelectAll(self, with_input_box: bool = False):
        """
    Description:
    ------------
    UnSelect all the items in the list.

    Attributes:
    ----------
    :param bool with_input_box: If the items have a dedicated input box for the check.
    """
        if self.component.options.items_type == "radio":
            raise ValueError(
                "It is not possible to select all radios from a same group, use check instead"
            )

        if self.component.options.items_type == "check" or with_input_box:
            return JsObjects.JsVoid('''
        %s.childNodes.forEach(function(dom, k){  
          const item = dom.querySelector('[name=input_box]');
          if (item != null){ 
            dom.querySelector('[name=input_box]').checked = false;
            dom.querySelector('[name=value]').setAttribute("data-valid", false);
        }})''' % self.varName)

        return JsObjects.JsVoid('''
      %s.childNodes.forEach( function(dom, k){  
        dom.querySelector('[name=value]').classList.remove('list_%s_selected');
        dom.querySelector('[name=value]').setAttribute("data-valid", false);
      })''' % (self.varName, self.component.options.items_type))
Example #2
0
    def caseBelow(self,
                  value: Union[int, primitives.JsDataModel],
                  js_funcs: Union[list, str],
                  include_value: bool = True):
        """
    Description:
    ------------
    Below case. The switch value should be below the value.

    Attributes:
    ----------
    :param Union[int, primitives.JsDataModel] value: Number. The pivot value.
    :param Union[list, str] js_funcs: The JavaScript functions.
    :param bool include_value: Optional. To specify if the pivot value is included.
    """
        value = JsUtils.jsConvertData(value, None)
        if include_value:
            self.__js.append(
                (JsObjects.JsVoid("(%s <= %s)" % (self.__selector, value)),
                 js_funcs))
        else:
            self.__js.append(
                (JsObjects.JsVoid("(%s < %s)" % (self.__selector, value)),
                 js_funcs))
        return self
Example #3
0
def var(name: str,
        value: Union[primitives.JsDataModel, str] = None,
        global_scope: bool = False,
        depth: bool = False):
    """
  Description:
  ------------
  Hoisting is JavaScript's default behavior of moving declarations to the top.

  Attributes:
  ----------
  :param str name: The variable name.
  :param Union[primitives.JsDataModel, str] value: Optional. The object.
  :param bool global_scope: Optional. The variable scope.
  :param bool depth: Optional. Set to true of it is a nested object.
  """
    if global_scope:
        name = "window['%s']" % name
    if value is None:
        return JsObjects.JsObject.JsObject.get(name)

    if global_scope:
        return JsObjects.JsVoid(
            "%s = %s" % (name, JsUtils.jsConvertData(value, None, depth)))

    return JsObjects.JsVoid("var %s = %s" %
                            (name, JsUtils.jsConvertData(value, None, depth)))
Example #4
0
  def connect(self, url=None, port=None, protocol=None, from_config=None):
    """
    Description:
    ------------
    n order to communicate using the WebSocket protocol, you need to create a WebSocket object; this will automatically attempt to open the connection to the server.

    Related Pages:

      https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications

    Attributes:
    ----------
    :param url: String. The URL to which to connect; this should be the URL to which the WebSocket server will respond.
        This should use the URL scheme wss://, although some software may allow you to use the insecure ws:// for local connections.
    :param protocol: String or List. Either a single protocol string or an array of protocol strings.
    :param from_config:
    """
    if from_config is not None:
      self._src._props['js']['builders'].add("var %s = new WebSocket(%s)" % (self._selector, from_config.address))
      self.__connect = "new WebSocket(%s)" % from_config.address
      return JsObjects.JsVoid("var %s = new WebSocket(%s)" % (self._selector, from_config.address))

    prefix = "wss" if self.secured else 'ws'
    if protocol is None:
      self._src._props['js']['builders'].add(
        "var %s = new WebSocket('%s://%s:%s')" % (self._selector, prefix, url, port))
      self.__connect = "new WebSocket('%s://%s:%s')" % (prefix, url, port)
      return JsObjects.JsVoid("var %s = new WebSocket('%s://%s:%s')" % (self._selector, prefix, url, port))

    protocol = JsUtils.jsConvertData(protocol, None)
    self._src._props['js']['builders'].add(
      "var %s = new WebSocket('%s://%s:%s', %s)" % (self._selector, prefix, url, port, protocol))
    self.__connect = "new WebSocket('%s://%s:%s', %s)" % (prefix, url, port, protocol)
    return JsObjects.JsVoid("var %s = new WebSocket('%s://%s:%s', %s)" % (self._selector, prefix, url, port, protocol))
Example #5
0
    def hide(self, target_ids=None, options=None):
        """
    Description:
    -----------
    This API hides specified targets.

    You can specify multiple targets by giving an array that includes id as String.
    If no argument is given, all of targets will be hidden.

    Related Pages:

      https://c3js.org/reference.html#api-hide

    Attributes:
    ----------
    :param target_ids:
    :param options:
    """
        if target_ids is None and options is None:
            return JsObjects.JsVoid("%s.show()" % self._selector)

        target_ids = JsUtils.jsConvertData(target_ids, None)
        options = JsUtils.jsConvertData(options, None)
        return JsObjects.JsVoid("%s.show(%s, %s)" %
                                (self._selector, target_ids, options))
Example #6
0
    def unSelectAll(self, with_input_box=False):
        """
    Description:
    ------------
    UnSelect all the items in the list

    Attributes:
    ----------
    :param with_input_box: Boolean. If the items have a dedicated input box for the check
    """
        if self._src._jsStyles['items_type'] == "radio":
            raise Exception(
                "It is not possible to select all radios from a same group, use check instead"
            )

        if self._src._jsStyles['items_type'] == "check" or with_input_box:
            return JsObjects.JsVoid('''
        %s.childNodes.forEach( function(dom, k){  
          const item = dom.querySelector('[name=input_box]');
          if (item != null){ 
            dom.querySelector('[name=input_box]').checked = false;
            dom.querySelector('[name=value]').setAttribute("data-valid", false);
        }})''' % self.varName)

        return JsObjects.JsVoid('''
      %s.childNodes.forEach( function(dom, k){  
        dom.querySelector('[name=value]').setAttribute("data-valid", false);
      })''' % self.varName)
Example #7
0
def recordset(name: str,
              value: Union[primitives.JsDataModel, str] = None,
              global_scope: bool = False):
    """
  Description:
  ------------
  Hoisting is JavaScript's default behavior of moving declarations to the top.
  Create a recordset variable on the JavaScript side (a list of dictionaries).

  Attributes:
  ----------
  :param str name: The variable name.
  :param Union[primitives.JsDataModel, str] value: Optional. The object.
  :param bool global_scope: Optional. The variable scope.
  """
    if global_scope:
        name = "window['%s']" % name
    if value is None:
        return JsObjects.JsArray.JsRecordSet.get(name)

    if global_scope:
        return JsObjects.JsVoid("%s = %s" %
                                (name, JsUtils.jsConvertData(value, None)))

    return JsObjects.JsVoid("var %s = %s" %
                            (name, JsUtils.jsConvertData(value, None)))
Example #8
0
    def caseRange(self,
                  min: Union[int, primitives.JsDataModel],
                  max: Union[int, primitives.JsDataModel],
                  js_funcs: Union[list, str],
                  include_value: bool = True):
        """
    Description:
    ------------
    Range case. The value should be within the range [min, max].

    Attributes:
    ----------
    :param Union[int, primitives.JsDataModel] max: The min value for this range.
    :param Union[int, primitives.JsDataModel] min: The max value for this range.
    :param Union[list, str] js_funcs: The JavaScript functions.
    :param bool include_value: Optional. To specify if the pivot value is included.
    """
        max = JsUtils.jsConvertData(max, None)
        min = JsUtils.jsConvertData(min, None)
        if include_value:
            self.__js.append((JsObjects.JsVoid(
                "(%s <= %s) && (%s <= %s)" %
                (min, self.__selector, self.__selector, max)), js_funcs))
        else:
            self.__js.append((JsObjects.JsVoid(
                "(%s < %s) && (%s < %s)" %
                (min, self.__selector, self.__selector, max)), js_funcs))
        return self
Example #9
0
    def case(self,
             value,
             js_funcs: Union[list, str],
             strict: bool = False,
             profile: Optional[Union[dict, bool]] = None):
        """
    Description:
    ------------

    Attributes:
    ----------
    :param value: Object. The pivot value.
    :param Union[list, str] js_funcs: The JavaScript functions.
    :param bool strict:
    :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage.
    """
        if strict:
            self.__js.append(
                (JsObjects.JsVoid("(%s === %s)" % (self.__selector, value)),
                 js_funcs))
        else:
            self.__js.append(
                (JsObjects.JsVoid("(%s == %s)" % (self.__selector, value)),
                 js_funcs))
        self.profile = profile
        return self
Example #10
0
    def columns(self, headers=None, rows=None, values=None, options=None):
        """
    Description:
    -----------

    Attributes:
    ----------
    :param headers:
    :param rows:
    :param values:
    :param options:
    """
        if headers is None and rows is None and values is None:
            raise Exception("Header, rows or values must be defined")

        if headers is not None:
            # If this variable is used it means the definition should be fully supplied and the default style will not be applied
            return JsObjects.JsVoid(
                "%s;%s" % (self.getColumns.forEach("rec.delete()").toStr(),
                           self.addColumns(headers, options=options).toStr()))

        if rows is not None or values is not None:
            rows_fields = self._parent.options.get({}, "rows_def").get(
                "fields", [])
            if rows is None and rows_fields:
                print(rows_fields)
                values = JsObjects.JsObjects.get(
                    "(function(d){var results = []; d.forEach(function(rec){if(typeof rec === 'string'){rec = {'field': rec, 'title': rec}}; results.push( Object.assign(rec, %s))}); return results})(%s)"
                    % (JsUtils.jsConvertData(
                        self._parent.options.get({}, "columns_def"),
                        None), values or []))
                return JsObjects.JsVoid("%s;%s" % (self.getColumns.forEach(
                    "if(!(%s.includes(rec.getField()))){rec.delete()}" %
                    rows_fields).toStr(), self.addColumns(values).toStr()))
            else:
                rows = JsObjects.JsObjects.get(
                    "(function(d){var results = []; d.forEach(function(rec){if(typeof rec === 'string'){rec = {'field': rec, 'title': rec}}; results.push( Object.assign(rec, %s))}); return results})(%s)"
                    % (JsUtils.jsConvertData(
                        self._parent.options.get({}, "rows_def"), None), rows
                       or []))
                values = JsObjects.JsObjects.get(
                    "(function(d){var results = []; d.forEach(function(rec){if(typeof rec === 'string'){rec = {'field': rec, 'title': rec}}; results.push( Object.assign(rec, %s))}); return results})(%s)"
                    % (JsUtils.jsConvertData(
                        self._parent.options.get({}, "columns_def"),
                        None), values or []))
                return JsObjects.JsVoid(
                    "%s;%s" % (self.getColumns.forEach("rec.delete()").toStr(),
                               "%s + %s" % (self.addColumns(rows).toStr(),
                                            self.addColumns(values).toStr())))
Example #11
0
    def abort(self, reason=None):
        """
    Description:
    ------------
    The abort() method of the WritableStream interface aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be immediately moved to an error state, with any queued writes discarded.

    Related Pages:

      https://developer.mozilla.org/en-US/docs/Web/API/WritableStream/abort
    """
        if reason is None:
            return JsObjects.JsPromise("%s.abort()" % self.varId)

        reason = JsUtils.jsConvertData(reason, None)
        return JsObjects.JsPromise("%s.abort(%s)" % (self.varId, reason))
Example #12
0
 def current(self):
     """
 Description:
 ------------
 Get the current value from a LI item event
 """
     return JsObjects.JsVoid("this.querySelector('[name=value]').innerHTML")
Example #13
0
    def setData(self, data):
        """

    :return:
    """
        return JsObjects.JsVoid(
            "%s.setData(%s)" % (self.varId, JsUtils.jsConvertData(data, None)))
Example #14
0
    def sendText(self,
                 components: List[primitives.HtmlModel],
                 attrs: dict = None):
        """
    Description:
    ------------
    Send a complex message from components.

    Related Pages:

      https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications

    Attributes:
    ----------
    :param List[primitives.HtmlModel] components: The list of HTML components (it will get the dom.content
      automatically)
    :param dict attrs: Optional. Attach some static attributes to the request
    """
        from epyk.core.data import primitives
        from epyk.core.data import datamap

        dfl_attrs = {"type": 'message', 'date': primitives.date()}
        if attrs is not None:
            dfl_attrs.update(attrs)
        data = JsUtils.jsConvertData(datamap(components, attrs=dfl_attrs),
                                     None)
        return JsObjects.JsVoid("%(varName)s.send(JSON.stringify(%(data)s))" %
                                {
                                    "varName": self._selector,
                                    "connect": self.__connect,
                                    "data": data
                                })
Example #15
0
    def contextMenu(self, menu, jsFncs=None, profile=False):
        """
    Description:
    ------------
    Add a context menu to an item in the list.

    Attributes:
    ----------
    :param menu:
    :param jsFncs: List. The Javascript functions
    :param profile: Boolean or Dictionary. Optional. A flag to set the component performance storage
    """
        if not hasattr(menu, 'source'):
            menu = self._src._report.ui.menus.contextual(menu)
        self.context_menu = menu
        menu.source = self
        new_js_fncs = (jsFncs or []) + [
            self._report.js.objects.mouseEvent.stopPropagation(),
            self.context_menu.dom.css(
                {
                    "display": 'block',
                    'left':
                    self._report.js.objects.mouseEvent.clientX + "'px'",
                    'top': self._report.js.objects.mouseEvent.clientY + "'px'"
                }),
            self._report.js.objects.mouseEvent.preventDefault()
        ]
        return JsObjects.JsVoid('''
      %s.lastChild.addEventListener("contextmenu", function(event){%s});
      ''' % (self.varName, JsUtils.jsConvertFncs(new_js_fncs, toStr=True)))
Example #16
0
    def connect(self,
                script: Optional[str] = None,
                content: Optional[str] = None,
                url: Optional[str] = None):
        """
    Description:
    ------------
    Create the worker content.

    Only one of the three parameter is needed.

    .. note::

      The JavaScript content used in a web worker need to be written in a way that he can be put in one line.
      In order to be compatible with Jupyter this content need to be loaded from Js and this can only be done by
      loading a plain text in one line.

    Related Pages:

      https://www.w3schools.com/html/html5_webworkers.asp
      https://www.html5rocks.com/en/tutorials/workers/basics/

    Attributes:
    ----------
    :param Optional[str] script: Optional. The full path of the file with the javaScript content.
    :param Optional[str] content: Optional. The JavaScript content.
    :param Optional[str] url: Optional. The link of the worker module to be included to the page.
    """
        if not self.__server or content is not None:
            script_content = [
                'if(document.getElementById("js_%(id)s") != null){document.getElementById("js_%(id)s").remove()}'
                % {
                    "id": self._selector
                }, 'var wkScript = document.createElement("script")',
                'wkScript.setAttribute("id", "js_%s")' % self._selector
            ]
            if script is not None:
                with open(script) as f:
                    script_content.append('wkScript.textContent = "%s"' %
                                          f.read().strip().replace("\n", ""))
            elif url is not None:
                script_content.append('wkScript.setAttribute("src", %s)' %
                                      JsUtils.jsConvertData(url, None))
            else:
                script_content.append('wkScript.textContent = "%s"' %
                                      content.strip().replace("\n", ""))
            script_content.append('document.head.appendChild(wkScript)')
            self.page.properties.js.add_builders(
                '''
%(content)s; var blob_%(selector)s = new Blob([document.querySelector('#js_%(selector)s').textContent ], {type: "text/javascript"})
%(selector)s = new Worker(window.URL.createObjectURL(blob_%(selector)s))''' % {
                    "content": JsUtils.jsConvertFncs(script_content,
                                                     toStr=True),
                    'selector': self._selector
                })
        else:
            self.page.properties.js.add_builders("%s = new Worker('%s')" %
                                                 (self._selector, script))
        return JsObjects.JsVoid("%s = new Worker('%s')" %
                                (self._selector, script))
Example #17
0
    def addEventListener(self,
                         event_type: str,
                         js_funcs: Union[list, str],
                         profile: Optional[Union[dict, bool]] = None):
        """
    Description:
    ------------

    Attributes:
    ----------
    :param str event_type: The event type.
    :param Union[list, str] js_funcs: Javascript functions.
    :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage.
    """
        event_type = JsUtils.jsConvertData(event_type, None)
        return JsObjects.JsVoid(
            "%(varName)s.addEventListener(%(eventType)s, function (event) {%(data)s})"
            % {
                "varName":
                self._selector,
                'eventType':
                event_type,
                "data":
                JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile)
            })
Example #18
0
 def clear(self):
   """
   Description:
   ------------
   Clear all the items in the list.
   """
   return JsObjects.JsVoid("%s.innerHTML = ''" % self._src.dom.varName)
Example #19
0
 def objects(self):
   """
   Description:
   -----------
   Interface to the main Javascript Classes and Primitives
   """
   return JsObjects.JsObjects(self)
Example #20
0
  def new(self, html_code, options, js_code):
    """
    Description:
    -----------

    Attributes:
    ----------
    :param html_code: String. Optional. An identifier for this component (on both Python and Javascript side).
    :param options:
    :param js_code:
    """
    options = JsUtils.jsConvertData(options, None)
    if js_code is not None:
      return JsObjects.JsVoid('%s = new frappe.Chart("#%s", %s)' % (js_code, html_code, options))

    return JsObjects.JsVoid('new frappe.Chart("#%s", %s)' % (html_code, options))
Example #21
0
 def index(self):
     """
 Description:
 ------------
 Get the index of the selected option.
 """
     return JsObjects.JsVoid("%(varId)s.index" % {"varId": self.varId})
Example #22
0
  def connect(self, script=None, content=None):
    """
    Description:
    ------------

    Related Pages:

      https://www.w3schools.com/html/html5_webworkers.asp
      https://www.html5rocks.com/en/tutorials/workers/basics/

    Attributes:
    ----------
    :param script: String.
    :param content: String.
    """
    if not self.__server or content is not None:
      # load the file and put this to Js Blobs
      if script is not None:
        with open(script) as f:
          self._src._props['js']['workers']['js_%s' % self._selector] = f.read()
      else:
        self._src._props['js']['workers']['js_%s' % self._selector] = content
      self._src._props['js']['builders'].add('''
        var blob_%(selector)s = new Blob([document.querySelector('#js_%(selector)s').textContent ], {type: "text/javascript"})
        %(selector)s = new Worker(window.URL.createObjectURL(blob_%(selector)s))''' % {'selector': self._selector})
    else:
      self._src._props['js']['builders'].add("%s = new Worker('%s')" % (self._selector, script))
    return JsObjects.JsVoid("%s = new Worker('%s')" % (self._selector, script))
Example #23
0
 def load(self,
          data: Union[str, primitives.JsDataModel],
          js_code: Union[str, primitives.JsDataModel] = None):
     js_code = JsUtils.jsConvertData(
         js_code or '%s_data' % self.component.htmlCode, None)
     return JsObjects.JsVoid("window[%s] = %s" %
                             (js_code, JsUtils.jsConvertData(data, None)))
Example #24
0
    def store(self,
              delimiter: str = None,
              data_type: str = None,
              js_code: Union[str, primitives.JsDataModel] = None):
        """
    Description:
    ------------

    Attributes:
    ----------
    :param str delimiter: Optional. The file delimiter.
    :param str data_type: Optional. The data type like json for example.
    :param Union[str, primitives.JsDataModel] js_code: Optional.
    """
        from epyk.core.data import events

        delimiter = delimiter or self.component.options.delimiter
        data_type = data_type or self.component.options.format
        js_code = JsUtils.jsConvertData(
            js_code or '%s_data' % self.component.htmlCode, None)
        if data_type.endswith("json"):
            value = events.data.jsonParse()
        else:
            value = events.data.fileToDict(delimiter)
        return JsObjects.JsVoid("window[%s] = %s" %
                                (js_code, JsUtils.jsConvertData(value, None)))
Example #25
0
    def setSize(self, width: Union[int, primitives.JsDataModel],
                height: Union[int, primitives.JsDataModel]):
        """
    Description:
    -----------
    Set the size of the canvas. This is automatically done on a window resize.

    Related Pages:

      https://visjs.github.io/vis-network/docs/network/

    Attributes:
    ----------
    :param Union[int, primitives.JsDataModel] width: The width
    :param Union[int, primitives.JsDataModel] height: The height
    """
        if isinstance(width, int):
            width = "%spx" % width

        if isinstance(height, int):
            height = "%spx" % height
        return JsObjects.JsVoid(
            "%s.setSize(%s, %s)" %
            (self.varId, JsUtils.jsConvertData(
                width, None), JsUtils.jsConvertData(height, None)))
Example #26
0
    def addTraces(self, traces, position=None, html_code=None):
        """
    Description:
    ------------
    This function has comparable performance to Plotly.react and is faster than redrawing the whole plot
    with Plotly.newPlot.

    Related Pages:

      https://plot.ly/javascript/plotlyjs-function-reference/#plotlynewplot

    Attributes:
    ----------
    :param traces:
    :param position: Integer.
    :param html_code: String. Optional. DOM node or string id of a DOM node.
    """
        traces = JsUtils.jsConvertData(traces, None)
        if position is None:
            return JsObject.JsObject.get(
                "Plotly.addTraces(%s, %s)" %
                (html_code or self.component.dom.varName, traces))

        position = JsUtils.jsConvertData(position, None)
        return JsObjects.JsVoid(
            "Plotly.addTraces(%s, %s, %s)" %
            (html_code or self.component.dom.varName, traces, position))
Example #27
0
    def updateOptions(self,
                      new_options,
                      redraw_paths=False,
                      animate=True,
                      update_synced_charts=True):
        """
    Description:
    -----------
    This method allows you to update the configuration object by passing the options as the first parameter.
    The new config object is merged with the existing config object preserving the existing configuration.

    Related Pages:

      https://apexcharts.com/docs/methods/#updateOptions

    Attributes:
    ----------
    :param new_options: Dictionary. The configuration object to merge on the existing one.
    :param redraw_paths: Boolean. Optional. When the chart is re-rendered, should it draw from the existing paths or
    completely redraw the chart paths from the beginning. By default, the chart is re-rendered from the existing paths
    :param animate: Boolean. Optional. Should the chart animate on re-rendering.
    :param update_synced_charts: Boolean. Optional. All the charts in a group should also update when one chart in a
    group is updated.
    """
        new_options = JsUtils.jsConvertData(new_options, None, depth=True)
        redraw_paths = JsUtils.jsConvertData(redraw_paths, None)
        animate = JsUtils.jsConvertData(animate, None)
        update_synced_charts = JsUtils.jsConvertData(update_synced_charts,
                                                     None)
        return JsObjects.JsVoid("%s.updateOptions(%s, %s, %s, %s)" %
                                (self.varName, new_options, redraw_paths,
                                 animate, update_synced_charts))
Example #28
0
    def exec(self, html_code, method_name, options=None):
        """
    Description:
    -----------
    If you want to call chart methods without referencing the instance of the chart,
    you can call the exec() method directly.
    The exec() method takes chartID as the first parameter and finds the chart instance based on that ID to execute
    method on that chart instance.

    Related Pages:

      https://apexcharts.com/docs/methods/#exec

    Attributes:
    ----------
    :param html_code: String. An identifier for this component (on both Python and Javascript side).
    :param method_name: String. Any function which can directly be called on chart instance can be named in method
    parameter.
    :param options: Dictionary. The parameters which are accepted in the original method will be passed here in the
    same order.
    """
        html_code = JsUtils.jsConvertData(html_code, None)
        method_name = JsUtils.jsConvertData(method_name, None)
        options = JsUtils.jsConvertData(options or {}, None, depth=True)
        return JsObjects.JsVoid("ApexCharts.exec(%s, %s, %s)" %
                                (html_code, method_name, options))
Example #29
0
    def setHeading(self, value):
        """
    https://developers.google.com/maps/documentation/javascript/maptypes

    :param value:
    :return:
    """
        return JsObjects.JsVoid("%s.setHeading(%s)" % (self.varId, value))
Example #30
0
  def receive(self, jsFncs):
    """
    Description:
    ------------

    :param jsFncs:
    """
    return JsObjects.JsVoid("%(varName)s.onmessage = function (event) {%(data)s}" % {"varName": self._selector, "data": JsUtils.jsConvertFncs(jsFncs, toStr=True)})