def const(name: str, value: Union[primitives.JsDataModel, str] = None, depth: bool = False): """ Description: ------------ The keyword const is a little misleading. It does NOT define a constant value. It defines a constant reference to a value. Redeclaring or reassigning an existing const variable, in the same scope, or in the same block, is not allowed: Related Pages: https://www.w3schools.com/js/js_const.asp Attributes: ---------- :param str name: The variable name. :param Union[primitives.JsDataModel, str] value: Object. Optional. The object. :param bool depth: Optional. Set to true of it is a nested object. """ return JsObjects.JsVoid("const %s = %s" % (name, JsUtils.jsConvertData(value, None, depth)))
def onmessage(self, js_funcs: Optional[Union[list, str]], profile: Optional[Union[dict, bool]] = None): """ Description: ------------ Fired when data is received through a WebSocket. Also available via the onmessage property. Related Pages: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications Attributes: ---------- :param Optional[Union[list, str]] js_funcs: Javascript functions. :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage. """ if not isinstance(js_funcs, list): js_funcs = [js_funcs] self.page.js.onReady( "%s.onmessage = function (event) {%s}" % (self._selector, JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile))) return self
def onclose(self, js_funcs: Optional[Union[list, str]], profile: Optional[Union[dict, bool]] = None): """ Description: ------------ Fired when a connection with a WebSocket is closed. Also available via the onclose property. Related Pages: https://javascript.info/websocket Attributes: ---------- :param Optional[Union[list, str]] js_funcs: Javascript functions. :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage. """ if not isinstance(js_funcs, list): js_funcs = [js_funcs] self.page.js.onReady( "%s.onclose = function (event) {%s}" % (self._selector, JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile))) return self
def load(self, args): """ Description: ----------- Load data to the chart. You can specify multiple targets by giving an array that includes id as String. If no argument is given, all of targets will be toggles. Related Pages: https://c3js.org/reference.html#api-load Attributes: ---------- :param args: """ if isinstance(args, list): if not isinstance(args[0], list): args = {"columns": [args]} else: args = {"columns": args} args = JsUtils.jsConvertData(args, None) return JsObjects.JsVoid("%s.load(%s)" % (self._selector, args))
def draggable(self, jsFncs=None, options=None, profile=False, source_event=None): """ Description: ------------ Attributes: ---------- :param jsFncs: :param options: :param profile: :param source_event: """ jsFncs = jsFncs or [] if not isinstance(jsFncs, list): jsFncs = [jsFncs] jsFncs.append('event.dataTransfer.setData("text", value)') self._jsStyles[ 'draggable'] = "function(event, value){%s} " % JsUtils.jsConvertFncs( jsFncs, toStr=True) return self
def draggable(self, js_funcs: Optional[Union[list, str]] = None, options: Optional[dict] = None, profile: Optional[Union[bool, dict]] = None, source_event: Optional[str] = None): """ Description: ------------ Attributes: ---------- :param Optional[Union[list, str]] js_funcs: Optional. Javascript functions. :param Optional[dict] options: Optional. Specific Python options available for this component. :param Optional[Union[bool, dict]] profile: Optional. A flag to set the component performance storage. :param Optional[str] source_event: Optional. The source target for the event. """ js_funcs = js_funcs or [] if not isinstance(js_funcs, list): js_funcs = [js_funcs] js_funcs.append('event.dataTransfer.setData("text", value)') self.options.draggable = "function(event, value){%s} " % JsUtils.jsConvertFncs( js_funcs, toStr=True, profile=profile) return self
def every(self, jsFncs, jsValue=None): """ The every() method checks if all elements in an array pass a test (provided as a function). Data Structure used in this method is like obj(val, index, arra) Example Documentation https://www.w3schools.com/jsref/jsref_every.asp :param jsFncs: A function to be run for each element in the array :param jsValue: Optional. A value to be passed to the function to be used as its "this" value. :return: None """ jsFncs = JsUtils.jsConvertFncs(jsFncs) if jsValue is None: return JsFncs.JsFunction( "%s.every(function(val, index, arr){%s})" % (self.varId, ";".join(jsFncs))) return JsFncs.JsFunction( "%s.every(function(val, index, arr){%s}, %s)" % (self.varId, ";".join(jsFncs), jsValue))
def map(self, jsFnc): """ Description: ----------- The map() method creates a new array with the results of calling a function for every array element. Usage:: jsObj.console.log(jsObj.objects.array.get("MyArray").map([ jsObj.data.loop.val * jsObj.math.max(jsObj.data.loop.arr.toArgs()), jsObj.return_(jsObj.data.loop.val)])) Related Pages: https://www.w3schools.com/jsref/jsref_map.asp Attributes: ---------- :param jsFnc: function(currentValue, index, arr) Required. A function to be run for each element in the array. :return: An Array containing the results of calling the provided function for each element in the original array. """ jsFnc = JsUtils.jsConvertFncs(jsFnc) if self.varName is not None: return JsArray( "%s = %s" % (self.varId, JsArray( "%s.map(function(value, index, arr){%s; return value})" % (self.varId, ";".join(jsFnc)), isPyData=False)), isPyData=False) return JsArray("%s.map(function(value, index, arr){%s})" % (self.varId, ";".join(jsFnc)), isPyData=False)
def delete(self, jsNumber): """ Description: ----------- Since JavaScript arrays are objects, elements can be deleted by using the JavaScript operator Using delete may leave undefined holes in the array. Use pop() or shift() instead. Usage:: jsObj.objects.array.new([2, 5, 12, -3], "MyArray") jsObj.objects.array.get("MyArray").delete(2) Related Pages: https://www.w3schools.com/js/js_array_methods.asp Attributes: ---------- :param jsNumber: The index of the value in the array to be removed :return: Void, The Javascript String """ jsNumber = JsUtils.jsConvertData(jsNumber, None) return JsFncs.JsFunction("delete %s[%s]" % (self.varId, jsNumber))
def timeRangeError(self, js_funcs: Union[list, str], profile: Optional[Union[dict, bool]] = None): """ Description: ------------ Called if maxTime and minTime, or disableTimeRanges is set and an invalid time is manually entered into the timepicker input. Fires before change event. Related Pages: https://github.com/jonthornton/jquery-timepicker#timepicker-plugin-for-jquery Attributes: ---------- :param Union[list, str] js_funcs: Javascript functions. :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage. """ js_funcs = JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile) return JsObjects.JsObjects.get( "%s.on('timeRangeError', function() {%s})" % (self.component.dom.jquery.varId, js_funcs))
def forEach(self, jsFnc, value="value"): """ Description: ----------- The forEach() method calls a provided function once for each element in an array, in order. Usage:: jsObj.objects.get("MyObject").keys().forEach([ jsObj.console.log(jsObj.data.loop.val)]) Related Pages: https://www.w3schools.com/jsref/jsref_foreach.asp Attributes: ---------- :param jsFnc: function(currentValue, index, arr) Required. A function to be run for each element in the array. :return: Void, The Javascript String """ jsFnc = JsUtils.jsConvertFncs(jsFnc) return JsFncs.JsFunction("%s.forEach(function(%s, index, arr){%s})" % (self.varId, value, ";".join(jsFnc)))
def loadHtml(self, components: List[primitives.HtmlModel], append: bool = False, profile: Optional[Union[dict, bool]] = None): """ Description: ------------ Load during a Javascript event a component within the one using this method. This cannot be tested during the Python execution and should be tested in the browser. Tip: It is possible to add a break point to debug in the browser by adding. Usage:: d = page.ui.div().css({"border": "1px solid black"}) b = page.ui.button("test") b.click([ page.js.console.debugger, d.dom.loadHtml(page.ui.texts.label("test label").css({"color": 'blue', 'float': 'none'})) ]) Attributes: ---------- :param List[primitives.HtmlModel] components: The different HTML objects to be added to the component. :param bool append: Mention if the component should replace or append the data. :param Optional[Union[dict, bool]] profile: Optional. A flag to set the component performance storage. :return: The Javascript string to be added to the page """ if not isinstance(components, list): components = [components] js_funcs = [] for i, h in enumerate(components): h.options.managed = False js_funcs.append(self.page.js.objects.new(str(h), isPyData=True, varName="obj_%s" % i)) js_funcs.append(self.innerHTML(self.page.js.objects.get("obj_%s" % i), append=append).r) return JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile)
def __register_records_fnc(self, fnc_name, fnc_def, fnc_pmts=None, profile=False): """ This function will attach to the report object only the javascript functions used during the report :param fnc_name: :param fnc_def: :param fnc_pmts: :return: """ fnc_pmts = ["data"] + (fnc_pmts or []) if not fnc_name in self._js_src.get('js', {}).get('functions', {}): self._js_src.setdefault('js', {}).setdefault( 'functions', {})[fnc_name] = { 'content': "var result = []; %s;return result" % JsUtils.cleanFncs(fnc_def), 'pmt': fnc_pmts }
def makeCode(self, data: Union[str, primitives.JsDataModel]): """ Description: ------------ Make another code. Usage: ----- qrcode = page.ui.qrcode() button = page.ui.button("Write Test") button.click([qrcode.js.makeCode("Test")]) Related Pages: https://davidshimjs.github.io/qrcodejs/ Attributes: ---------- :param Union[str, primitives.JsDataModel] data: The text to be used to build to code. """ data = JsUtils.jsConvertData(data, None) return JsObjects.JsObjects.get('%s.makeCode(%s)' % (self.varName, data))
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. """ 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) })
def postMessage(self, data, components: List[primitives.HtmlModel] = None): """ Description: ------------ Post a message to the webworker. Usage:: page.ui.button("Add").click([w2.postMessage({'cmd': 'add', 'value1': 2}, components=[(slider, "value2")])]) Related Pages: https://www.html5rocks.com/en/tutorials/workers/basics/ Attributes: ---------- :param data: :param List[primitives.HtmlModel] components: A list of html component or tuples with the alias """ if components is not None: data = JsData.Datamap(components=components, attrs=data) else: data = JsUtils.jsConvertData(data, None) return JsObjects.JsVoid("%s.postMessage(%s)" % (self._selector, data))
def let(name: str, value: Union[primitives.JsDataModel, str], depth: bool = False): """ Description: ------------ Redeclaring a variable using the let keyword can solve this problem. Redeclaring a variable inside a block will not redeclare the variable outside the block: Redeclaring a var variable with let, in the same scope, or in the same block, is not allowed: Related Pages: https://www.w3schools.com/js/js_let.asp Attributes: ---------- :param str name: The variable name. :param Union[primitives.JsDataModel, str] value: Optional. The object. :param bool depth: Optional. Set to true of it is a nested object. """ return JsObjects.JsVoid("let %s = %s" % (name, JsUtils.jsConvertData(value, None, depth)))
from epyk.core.js import Js from epyk.core.js import JsUtils from epyk.core.js.fncs import JsFncsRecords jsObj = Js.JsBase() jsObj.registerFunction("row-buckets") jsObj.addKeyEvent(jsObj.window.alert("test alert"), 13) f = JsUtils.JsFile("RowBucket", path=r"../outs") f.writeReport(jsObj) f.close()
def get_data(self, js_code: Union[str, primitives.JsDataModel] = None): js_code = JsUtils.jsConvertData( js_code or '%s_data' % self.component.htmlCode, None) return JsObjects.JsObjects.get("window[%s]" % js_code)
""" Create a HTML page only from JavaScript functions """ from epyk.core.js import Js from epyk.core.js import JsUtils from epyk.core.js.packages import JsDatatable from epyk.tests import test_statics # Create a blank Javascript Python object jsObj = Js.JsBase() # Write the results to a Javascript file with a Launcher f = JsUtils.JsFile("TestDatatable", path=test_statics.OUTPUT_PATHS) tab = JsDatatable.DatatableAPI(selector="table", setVar=False) cell = JsDatatable.CellAPI() f.writeJs([ tab.order().draw().destroy(), tab.data().length, cell.select().deselect(), tab.jquery_node().text("") ]) # Close the file and print the location of the launcher print(f.close(jsObj))
def __add__(self, value): return JsString("%s + %s" % (self.varId, JsUtils.jsConvertData(value, None)), isPyData=False)
def add(self, text: Union[str, primitives.JsDataModel], category: Union[str, primitives.JsDataModel] = None, name: str = None, fixed: bool = False, no_duplicate: bool = True): """ Description: ------------ Add item on the filters panel. When no_duplicate is set to False it is possible to pass a list. Attributes: ---------- :param Union[str, primitives.JsDataModel] text: The value to be added on the filter panel. :param Union[str, primitives.JsDataModel] category: :param str name: :param bool fixed: :param bool no_duplicate: """ text = JsUtils.jsConvertData(text, None) fixed = JsUtils.jsConvertData(fixed, None) if category is None: category = name or self.component._jsStyles['category'] name = name or category category = JsUtils.jsConvertData(category, None) name = JsUtils.jsConvertData(name, None) # Convert the option to a javascript object # TODO move this in a centralised place options, js_options = self.component._jsStyles, [] for k, v in options.items(): if isinstance(v, dict): row = [ "'%s': %s" % (s_k, JsUtils.jsConvertData(s_v, None)) for s_k, s_v in v.items() ] js_options.append("'%s': {%s}" % (k, ", ".join(row))) else: if str(v).strip().startswith("function"): js_options.append("%s: %s" % (k, v)) else: js_options.append("%s: %s" % (k, JsUtils.jsConvertData(v, None))) if no_duplicate: return JsObjects.JsObjects.get( '''if ((%(duplicated)s == -1) && (%(text)s != '')){ chipAdd(%(panel)s, {name: %(name)s, category: %(category)s, value: %(text)s, disabled: false, fixed: %(fixed)s}, {%(options)s}) } ''' % { 'name': name, 'category': category, 'duplicated': self.is_duplicated(text, category), 'panel': self.querySelector("div[name=panel]"), 'fixed': fixed, 'text': text, 'options': ",".join(js_options) }) return JsObjects.JsObjects.get( '''var itemLabel = %(text)s; if(Array.isArray(itemLabel)){ itemLabel.forEach(function(item){ chipAdd(%(panel)s, {name: %(name)s, category: %(category)s, value: item, disabled: false, fixed: %(fixed)s}, {%(options)s})})} else {chipAdd(%(panel)s, {name: %(name)s, category: %(category)s, value: itemLabel, disabled: false, fixed: %(fixed)s}, {%(options)s})} ''' % { 'name': name, 'category': category, 'panel': self.querySelector("div[name=panel]"), 'fixed': fixed, 'text': text, 'options': ",".join(js_options), "maxHeight": self.component._jsStyles["max_height"] })
def toStr(self): from epyk.core.js import JsUtils return JsUtils.jsConvertData("".join(self._js), None)
import pytest from epyk.core.js import Js from epyk.core.js import JsUtils from epyk.core.js.primitives import JsNumber jsObj = Js.JsBase() print(jsObj.objects.number.new(349.673, "MyNumber").toStr()) jsObj = Js.JsBase() f = JsUtils.JsFile(os.path.basename(__file__).split(".")[0], path=r"C:\Users\olivier\Documents\youpi\jsFiles") f.writeJs([ jsObj.objects.array.new([2, 5, 12, -3], "MyArray"), jsObj.objects.array.new([3, -9, 2, -6], "MyArray2"), jsObj.objects.array.new([], "MyArray3"), jsObj.console.log(jsObj.objects.array.get("MyArray3").concat(jsObj.objects.array.get("MyArray"), jsObj.objects.array.get("MyArray2"))), jsObj.console.log(jsObj.objects.array.get("MyArray").findIndex([ jsObj.if_(jsObj.data.loop.val <= 0, [ jsObj.return_(jsObj.objects.true)]).else_(jsObj.return_(jsObj.objects.false)), ])), jsObj.console.log(jsObj.objects.array.get("MyArray").map([ jsObj.data.loop.val * jsObj.math.max(jsObj.data.loop.arr.toArgs()), jsObj.return_(jsObj.data.loop.val) ])), jsObj.console.log("########"), # jsObj.console.log(jsObj.objects.array.get("MyArray")),
def add(self, value, css_attrs: dict = None, css_cls=None, before: bool = False, options: dict = None): """ Description: ------------ Add items to the list. Attributes: ---------- :param value: String | Dictionary. :param dict css_attrs: All the CSS attributes to be added to the LI component. :param css_cls: String. The CSS class to be added to the LI component. :param bool before: :param dict options: """ if isinstance(value, dict): js_values = [] for k, v in value.items(): js_values.append("%s: %s" % (k, JsUtils.jsConvertData(v, None))) value = "{%s}" % ",".join(js_values) else: if hasattr(value, 'dom'): value = value.dom.content value = JsUtils.jsConvertData(value, None) return JsObjects.JsVoid( ''' var item = %(value)s; var itemOptions = %(options)s; if(itemOptions.showdown){ var converter = new showdown.Converter({}); converter.setOption("display", "inline-block"); var content = item; if(typeof item.content !== 'undefined'){content = item.content}; content = converter.makeHtml(content).replace("<p>", "<p style='display:inline-block;margin:0'>"); item.content = content }; var li = document.createElement("LI"); %(shape)s(li, item, %(options)s); if(itemOptions.items_space){li.style.margin = "5px 0"; li.style.padding = "2px 0"}; %(comp)s.%(event)s(li) if(itemOptions.delete){ var close = document.createElement("i"); close.setAttribute("class", itemOptions.delete_icon); close.style.cursor = 'pointer'; close.style.position = 'absolute'; close.style.right = "0"; li.style.position = "relative"; close.onclick = function(event){this.parentNode.remove()}; for (const [key, value] of Object.entries(itemOptions.delete_position)){close.style[key] = value} li.lastChild.style.display = 'inline-block'; li.appendChild(close); const cls = %(cls)s; if (cls != null){li.classList.add(cls)} } ''' % { 'comp': self.varName, 'options': self.component.options.config_js(options), 'value': value, 'event': "prepend" if before else 'appendChild', 'cls': JsUtils.jsConvertData(css_cls, None), 'shape': "%s%s" % (self.component.options.prefix, self.component.options.items_type) })
def beforeShowDay(self, js_funcs, profile=None): self._config( "function (value){%s}" % JsUtils.jsConvertFncs(js_funcs, toStr=True, profile=profile), js_type=True)
def build(self, data=None, options=None, profile=False): if data: return "d3.select('#%(htmlCode)s').datum(%(data)s).transition().duration(500).call(%(chart)s); nv.utils.windowResize(%(chart)s.update)" % {'htmlCode': self.htmlCode, 'data': self.convert(data, options, profile), 'chart': self.dom.var} return JsUtils.jsConvertFncs([self.dom.set_var(True), self.dom.xAxis, self.d3.datum(self._datasets).call(self.dom.var), "nv.utils.windowResize(function() { %s.update() })" % self.dom.var], toStr=True)[4:]
def click(self, jsFnc, profile=False, source_event=None): self.onReady("%s.pie.dispatch.on('elementClick', function(event){ %s })" % (self.dom.varName, JsUtils.jsConvertFncs(jsFnc, toStr=True))) return self
def click(self, jsFnc, profile=False, source_event=None): self.onReady("%s.selectAll('.nv-bar').on('click', function(event){ %s })" % (self.d3.varId, JsUtils.jsConvertFncs(jsFnc, toStr=True))) return self
def hide(self): return JsUtils.jsWrap("%s.checked = true" % self.component.dom.varName)