def drag(self, move, start, up): onMove = getattr(self, "_onMove") onStart = getattr(self, "_onStart") onUp = getattr(self, "_onUp") self.onMoveFunction = move self.onStartFunction = start self.onUpFunction = up JS(""" this._element.drag(@{{onMove}},@{{onStart}},@{{onUp}}); """)
def hash(obj): JS(""" if (obj == null) return null; if (obj.$H) return obj.$H; if (obj.__hash__) return obj.__hash__(); if (obj.constructor == String || obj.constructor == Number || obj.constructor == Date) return obj; obj.$H = ++pyjslib.next_hash_id; return obj.$H; """)
def newItem(ht): print "History - new item", ht onHistoryChanged(ht) return JS(""" if(@{{historyToken}} == "" || @{{historyToken}} == null){ @{{historyToken}} = "#"; } $wnd.location.hash = encodeURI(@{{historyToken}}).replace('#','%23'); """)
def __createMethod(self, method): def inner(*args, **kargs): params = self.__encodeJSON(args) req = '{"method":"call","params":["%s", "%s", %s],"id":2}' % ( self.module, method, params) res = PyjamasExternalModule.http.syncPost( self.base + '/obj/handler', req) return self.__parseJSON(res)['result'] JS(""" @{{self}}[@{{method}}] = @{{inner}}; """)
def catchEvents(self, name, object): JS(''' var tmp = function(e) { var targ; if (!e) var e = $wnd.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) targ = targ.parentNode; if (targ.__ref) @{{object}}.dom_event(e, targ.__ref); else @{{object}}.dom_event(e, null); }; ''') name = name[0] self.activeEvents.append((name, object)) JS(''' var old_callback = this.element['on'+@{{name}}]; this.element['on'+@{{name}}] = function(e){if(old_callback){old_callback(e);}@{{!tmp}}(e);}; ''')
def strptime(datestring, format): try: tt = localtime( float( JS("strptime(@{{datestring}}.valueOf(), @{{format}}.valueOf()).getTime() / 1000.0" ))) tt.tm_isdst = -1 return tt except: raise ValueError( "Invalid or unsupported values for strptime: '%s', '%s'" % (datestring, format))
def circle(self, x, y, radius): """ Create and return a circle element. The circle will be centred around (x,y), and will have the given radius. We return a RaphaelElement object representing the circle. """ JS(""" this._element = this._canvas.circle(x, y, radius); """) return RaphaelElement(self._element)
def getrandbits(self, k): s = "" JS(""" var table = new Array(); for (var i = 0 ; i < @{{k}}/32; i++) { table[i] = (Math.random() * 4294967296).toString(32); } @{{s}} = table.join(""); """) rand = long(s, 32) mask = one.__lshift__(k).__sub__(one) return rand.__and__(mask)
def localtime(t=None): if t == None: t = time() date = JS("new Date(@{{t}}*1000)") dateOffset = date.getTimezoneOffset() tm = struct_time() tm_year = tm.tm_year = int(date.getFullYear()) tm_mon = tm.tm_mon = int(date.getMonth()) + 1 tm_mday = tm.tm_mday = int(date.getDate()) tm.tm_hour = int(date.getHours()) tm.tm_min = int(date.getMinutes()) tm.tm_sec = int(date.getSeconds()) tm.tm_wday = (int(date.getDay()) + 6) % 7 tm.tm_isdst = 0 if timezone == 60 * date.getTimezoneOffset() else 1 startOfYear = JS("new Date(@{{tm_year}},0,1)") # local time startOfYearOffset = startOfYear.getTimezoneOffset() startOfDay = JS("new Date(@{{tm_year}},@{{tm_mon}}-1,@{{tm_mday}})") dt = float(startOfDay.getTime() - startOfYear.getTime()) / 1000 dt = dt + 60 * (startOfYearOffset - dateOffset) tm.tm_yday = 1 + int(dt / 86400.0) return tm
def setAttrs(self, attrs): """ Set the value of multiple attributes at once. 'attrs' should be a dictionary mapping attribute names to values. The available attributes are listed in the description of the setAttr() method, above. """ for attr, value in attrs.items(): JS(""" this._element.attr(attr, value); """)
def set(self): """ Create and return a set element. This can be used to group elements together and operate on these elements as a unit. We return a RaphaelSetElement representing the set. """ JS(""" self._element = this._canvas.set(); """) return RaphaelSetElement(self._element)
def mktime(t): """mktime(tuple) -> floating point number Convert a time tuple in local time to seconds since the Epoch.""" tm_year = t[0] tm_mon = t[1] - 1 tm_mday = t[2] tm_hour = t[3] tm_min = t[4] tm_sec = t[5] date = JS( "new Date(@{{tm_year}}, @{{tm_mon}}, @{{tm_mday}}, @{{tm_hour}}, @{{tm_min}}, @{{tm_sec}})" ) # local time utc = JS( "Date.UTC(@{{tm_year}}, @{{tm_mon}}, @{{tm_mday}}, @{{tm_hour}}, @{{tm_min}}, @{{tm_sec}})" ) / 1000 ts = date.getTime() / 1000 if t[8] == 0: if ts - utc == timezone: return ts return ts + _dst return ts
def ellipse(self, x, y, xRadius, yRadius): """ Create and return an ellipse element. The ellipse will be centred around (x,y), and will have the given horizontal and vertical radius. We return a RaphaelElement object representing the ellipse. """ JS(""" this._element = this._canvas.ellipse(x, y, xRadius, yRadius); """) return RaphaelElement(self._element)
def getY(self): JS(''' var obj = this.element; var curtop = 0; if (obj.offsetParent) { curtop = obj.offsetTop while (obj = obj.offsetParent) { curtop += obj.offsetTop } } return curtop; ''')
def getX(self): JS(''' var obj = this.element; var curleft = 0; if (obj.offsetParent) { curleft = obj.offsetLeft while (obj = obj.offsetParent) { curleft += obj.offsetLeft } } return curleft; ''')
def __init__(self, tag=None, element=None): if tag is not None: JS(''' this.element = $doc.createElement(tag); ''') elif element is not None: self.element = element else: raise Exception("Cannot create Element without tag or element") self.element.__ref = self self.activeEvents = []
def match(self, string, pos=0, endpos=None): # If zero or more characters at the beginning of string match this # regular expression, return a corresponding MatchObject instance. Return # None if the string does not match the pattern. if not endpos is None: string = string[:endpos] else: endpos = len(string) if pos == 0: groups = self.match_code.Exec(string) if JS("@{{groups}} === null"): return None _groups = [] for i in list(groups): if JS("@{{i}} === null"): _groups.append(None) else: _groups.append(str(i)) groups = _groups elif pos >= len(string): return None else: # Strickly, we shouldn't use string[pos:] # The '^' pattern character should match at the real beginning of # the string and at positions just after a newline, but not # necessarily at the index where the search is to start. # Maybe, we should raise an error if there's a '^' in pat (not in []) groups = self.match_code.Exec(string[pos:]) if JS("@{{groups}} === null"): return None if groups.index != 0: return None _groups = [] for i in list(groups): if JS("@{{i}} === null"): _groups.append(None) else: _groups.append(str(i)) groups = _groups return SRE_Match(self, string, pos, endpos, groups, pos, None, None)
def text(self, x, y, text): """ Create and return a text element. The element will be placed at (x,y), and will display the given text. Note that you can embed newline ("\n") characters into the text to force line breaks. We return a RaphaelElement representing the text. """ JS(""" this._element = this._canvas.text(x, y, text); """) return RaphaelElement(self._element)
def image(self, src, x, y, width, height): """ Create and return an image element. The image will use 'src' as the URI to read the image data from. The top-left corner of the image will be at (x,y), and the image element will have the given width and height. We return a RaphaelElement object representing the image. """ JS(""" this._element = this._canvas.image(src, x, y, width, height); """) return RaphaelElement(self._element)
def jsObjectToPy(self, obj): JS(""" if (pyjslib.isArray(obj)) { for (var i in obj) obj[i] = this.jsObjectToPy(obj[i]); obj=new pyjslib.list(obj); } else if (pyjslib.isObject(obj)) { for (var i in obj) obj[i]=this.jsObjectToPy(obj[i]); obj=new pyjslib.dict(obj); } return obj; """)
def circle(self, x, y, radius): """ Create and return a circle element. The circle will be centred around (x,y), and will have the given radius. We return a RaphaelElement object representing the circle. """ JS(""" this['_element'] = this['_canvas']['circle'](@{{x}}, @{{y}}, @{{radius}}); this['_canvas']['safari'](); """) return RaphaelElement(self._element)
def trackstacklist(stack=None, limit=None): if stack is None: stack = JS('$pyjs.__active_exception_stack__') else: if JS("""@{{stack}} instanceof Array"""): stack = _exception_from_trackstack(stack) if stack is None: return '' stackstrings = [] msg = '' if limit is None: limit = -1 while stack and limit: JS("@{{msg}} = $pyjs.loaded_modules[@{{stack}}.module]['__track_lines__'][@{{stack}}['lineno']];") JS("if (typeof @{{msg}} == 'undefined') @{{msg}} = null;") if msg: stackstrings.append(msg + '\n') else: stackstrings.append('%s.py, line %d\n' % (stack.module, stack.lineno)) stack = stack.tb_next limit -= 1 return stackstrings
def set(self, data): """ Set array elements. Data argument can be a 1d/2d array or number used to set Ndarray elements, data used repetitively if consists of fewer elements than Ndarray. """ if isinstance(data, (list, tuple)): if pyjs_mode.optimized: if isinstance(data[0], (list, tuple, PyTypedArray)): data = [value for dat in data for value in dat] else: if not isinstance(data[0], (list, tuple, PyTypedArray)): data = [dat.valueOf() for dat in data] else: data = [value.valueOf() for dat in data for value in dat] dataLn = len(data) data = data.getArray() elif isinstance(data, (Ndarray, PyTypedArray)): data = data.getArray() dataLn = data.length else: if pyjs_mode.optimized: for index in xrange(self.__data.__data.length): JS("""@{{self}}['__data']['__data'][@{{index}}]=@{{data}};""" ) else: data = data.valueOf() for index in xrange(self.__data.__data.length): JS("""@{{self}}['__data']['__data'][@{{index}}]=@{{data}};""" ) return None if dataLn == self.__data.__data.length: for index in xrange(self.__data.__data.length): JS("""@{{self}}['__data']['__data'][@{{index}}]=@{{data}}[@{{index}}];""" ) else: for index in xrange(self.__data.__data.length): JS("""@{{self}}['__data']['__data'][@{{index}}]=@{{data}}[@{{index}}%@{{dataLn}}];""" ) return None
def newItem(ht): global historyToken if historyToken == ht: return onHistoryChanged(ht) return JS(""" if(@{{historyToken}} == "" || @{{historyToken}} == null){ @{{historyToken}} = "#"; } $wnd.location.hash = encodeURI(@{{historyToken}}).replace('#','%23'); """)
def translateGmapsObject(obj, fieldName, fields, pyToJs): JS(""" //console['log']("translateGmapsObject " + fieldNameXXX+"("+pyToJs+")") if (! (@{{fieldName}} in @{{fields}})) { //console['log']("nothing") return @{{obj}}; } else{ @{{action}} = @{{fields}}[@{{fieldName}}] //console['log']("action=" + action) if (@{{action}} == 'd') { //console['log']("is dict") // this newobj can be used in js and also in python, // like this "newobj['field']" var newobj = {} for (var i in @{{obj}}) // vai ficar disponivel como uma propriedade, no python! newobj[i] = $m['translateGmapsObject'](@{{obj}}[i], i, @{{fields}}, @{{pyToJs}}); return newobj } else if (@{{action}} == 'l') { if (@{{pyToJs}}) { var newobj = $m['listToJs'](@{{obj}}) //console['log']("is list py->js") for (var i in newobj){ newobj[i]=$m['translateGmapsObject']( newobj[i], @{{fieldName}} + "[]", @{{fields}},@{{pyToJs}} ) ; } return newobj }else{ //console['log']("is list js->py") var newobj = @{{list}}([]) for (var i in @{{obj}}) newobj['append']($m['translateGmapsObject']( @{{obj}}[i], @{{fieldName}} + "[]", @{{fields}},@{{pyToJs}} )); return newobj } } else { //console['log']("is special") return @{{action}}(@{{obj}}) } } """)
def translateGmapsObject(obj, fieldName, fields, pyToJs): JS(""" //console.log("translateGmapsObject " + fieldName+"("+pyToJs+")") if (! (fieldName in fields)) { //console.log("nothing") return obj; } else{ action = fields[fieldName] //console.log("action=" + action) if (action == 'd') { //console.log("is dict") // this newobj can be used in js and also in python, // like this "newobj.field" var newobj = {} for (var i in obj) // vai ficar disponivel como uma propriedade, no python! newobj[i] = Utils.translateGmapsObject(obj[i], i, fields, pyToJs); return newobj } else if (action == 'l') { if (pyToJs) { var newobj = Utils.listToJs(obj) //console.log("is list py->js") for (var i in newobj){ newobj[i]=Utils.translateGmapsObject( newobj[i], fieldName + "[]", fields,pyToJs ) ; } return newobj }else{ //console.log("is list js->py") var newobj = pyjslib.list([]) for (var i in obj) newobj.append(Utils.translateGmapsObject( obj[i], fieldName + "[]", fields,pyToJs )); return newobj } } else { //console.log("is special") return action(obj) } } """)
def getBBox(self): """ Return the bounding box for this element. We return a dictionary with 'x', 'y', 'width' and 'height' elements. """ JS(""" var bounds = this._element.getBBox(); var x = bounds.x; var y = bounds.y; var width = bounds.width; var height = bounds.height; """) return {'x': x, 'y': y, 'width': width, 'height': height}
def exportWiringCode(): JS(""" var a = document.createElement('a'); try{ var blob = new Blob([$doc.defaultView.editor.getSession()], {'type': 'text/plain'}); window.URL = window.URL || window.webkitURL; a.href = window.URL.createObjectURL(blob); a.download = 'WiringCode.ino'; a.click(); } catch(e){ console.log(e); } """)
def find_module(name, path=None): """find_module(name, [path]) -> (file, filename, (suffix, mode, type)) Search for a module. If path is omitted or None, search for a built-in, frozen or special module and continue search in sys.path. The module name cannot contain '.'; to search for a submodule of a package, pass the submodule name and the package's __path__.""" if path is not None: name = '.'.join(path) + '.' + name if JS("""typeof $pyjs['loaded_modules'][@{{name}}['valueOf']()] != 'undefined'"""): return (None, name, ('', '', JS_COMPILED)) # TODO: dynamic loading # if JS("$pyjs['options']['dynamic_loading']"): # return (jscode, name, ('js', '', JS_SOURCE)) raise ImportError("No module named %s" % name)
def rect(self, x, y, width, height, cornerRadius=0): """ Create and return a rectangle element. The rectangle will have its top-left corner at (x,y), and have the given width and height. If 'cornerRadius' is specified, the rectangle will have rounded corners with the given radius. We return a RaphaelElement object representing the rectangle. """ JS(""" this._element = this._canvas.rect(x, y, width, height, cornerRadius); """) return RaphaelElement(self._element)