laurent@371: # Copyright 2006 James Tauber and contributors laurent@371: # laurent@371: # Licensed under the Apache License, Version 2.0 (the "License"); laurent@371: # you may not use this file except in compliance with the License. laurent@371: # You may obtain a copy of the License at laurent@371: # laurent@371: # http://www.apache.org/licenses/LICENSE-2.0 laurent@371: # laurent@371: # Unless required by applicable law or agreed to in writing, software laurent@371: # distributed under the License is distributed on an "AS IS" BASIS, laurent@371: # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. laurent@371: # See the License for the specific language governing permissions and laurent@371: # limitations under the License. laurent@371: andrej@1872: # pylint: disable=too-many-function-args,undefined-variable laurent@371: laurent@371: # iteration from Bob Ippolito's Iteration in JavaScript laurent@371: laurent@371: from __pyjamas__ import JS laurent@371: laurent@371: # must declare import _before_ importing sys laurent@371: andrej@1736: laurent@371: def import_module(path, parent_module, module_name, dynamic=1, async=False): laurent@371: laurent@371: JS(""" laurent@371: var cache_file; laurent@371: laurent@371: if (module_name == "sys" || module_name == 'pyjslib') laurent@371: { laurent@371: /*module_load_request[module_name] = 1;*/ laurent@371: return; laurent@371: } laurent@371: laurent@371: if (path == null) laurent@371: { laurent@371: path = './'; laurent@371: } laurent@371: laurent@371: var override_name = sys.platform + "." + module_name; andrej@1730: if (((sys.overrides != null) && laurent@371: (sys.overrides.has_key(override_name)))) laurent@371: { laurent@371: cache_file = sys.overrides.__getitem__(override_name) ; laurent@371: } laurent@371: else laurent@371: { laurent@371: cache_file = module_name ; laurent@371: } laurent@371: laurent@371: cache_file = (path + cache_file + '.cache.js' ) ; laurent@371: laurent@371: //alert("cache " + cache_file + " " + module_name + " " + parent_module); laurent@371: laurent@371: /* already loaded? */ laurent@371: if (module_load_request[module_name]) laurent@371: { laurent@371: if (module_load_request[module_name] >= 3 && parent_module != null) laurent@371: { laurent@371: //onload_fn = parent_module + '.' + module_name + ' = ' + module_name + ';'; laurent@371: //pyjs_eval(onload_fn); /* set up the parent-module namespace */ laurent@371: } laurent@371: return; laurent@371: } laurent@371: if (typeof (module_load_request[module_name]) == 'undefined') laurent@371: { laurent@371: module_load_request[module_name] = 1; laurent@371: } laurent@371: andrej@1730: /* following a load, this first executes the script laurent@371: * "preparation" function MODULENAME_loaded_fn() laurent@371: * and then sets up the loaded module in the namespace laurent@371: * of the parent. laurent@371: */ laurent@371: laurent@371: onload_fn = ''; // module_name + "_loaded_fn();" laurent@371: laurent@371: if (parent_module != null) laurent@371: { laurent@371: //onload_fn += parent_module + '.' + module_name + ' = ' + module_name + ';'; laurent@371: /*pmod = parent_module + '.' + module_name; laurent@371: onload_fn += 'alert("' + pmod + '"+' + pmod+');';*/ laurent@371: } laurent@371: laurent@371: laurent@371: if (dynamic) laurent@371: { laurent@371: /* this one tacks the script onto the end of the DOM laurent@371: */ laurent@371: laurent@371: pyjs_load_script(cache_file, onload_fn, async); laurent@371: laurent@371: /* this one actually RUNS the script (eval) into the page. laurent@371: my feeling is that this would be better for non-async laurent@371: but i can't get it to work entirely yet. laurent@371: */ laurent@371: /*pyjs_ajax_eval(cache_file, onload_fn, async);*/ laurent@371: } laurent@371: else laurent@371: { laurent@371: if (module_name != "pyjslib" && laurent@371: module_name != "sys") laurent@371: pyjs_eval(onload_fn); laurent@371: } laurent@371: laurent@371: """) laurent@371: andrej@1749: laurent@371: JS(""" laurent@371: function import_wait(proceed_fn, parent_mod, dynamic) { laurent@371: laurent@371: var data = ''; laurent@371: var element = $doc.createElement("div"); laurent@371: $doc.body.appendChild(element); laurent@371: function write_dom(txt) { laurent@371: element.innerHTML = txt + '
'; laurent@371: } laurent@371: laurent@371: var timeoutperiod = 1; laurent@371: if (dynamic) laurent@371: var timeoutperiod = 1; laurent@371: laurent@371: var wait = function() { laurent@371: laurent@371: var status = ''; laurent@371: for (l in module_load_request) laurent@371: { laurent@371: var m = module_load_request[l]; laurent@371: if (l == "sys" || l == 'pyjslib') laurent@371: continue; laurent@371: status += l + m + " "; laurent@371: } laurent@371: laurent@371: //write_dom( " import wait " + wait_count + " " + status + " parent_mod " + parent_mod); laurent@371: wait_count += 1; laurent@371: laurent@371: if (status == '') laurent@371: { laurent@371: setTimeout(wait, timeoutperiod); laurent@371: return; laurent@371: } laurent@371: laurent@371: for (l in module_load_request) laurent@371: { laurent@371: var m = module_load_request[l]; laurent@371: if (l == "sys" || l == 'pyjslib') laurent@371: { laurent@371: module_load_request[l] = 4; laurent@371: continue; laurent@371: } laurent@371: if ((parent_mod != null) && (l == parent_mod)) laurent@371: { laurent@371: if (m == 1) laurent@371: { laurent@371: setTimeout(wait, timeoutperiod); laurent@371: return; laurent@371: } laurent@371: if (m == 2) laurent@371: { laurent@371: /* cheat and move app on to next stage */ laurent@371: module_load_request[l] = 3; laurent@371: } laurent@371: } laurent@371: if (m == 1 || m == 2) laurent@371: { laurent@371: setTimeout(wait, timeoutperiod); laurent@371: return; laurent@371: } laurent@371: if (m == 3) laurent@371: { laurent@371: //alert("waited for module " + l + ": loaded"); laurent@371: module_load_request[l] = 4; laurent@371: mod_fn = modules[l]; laurent@371: } laurent@371: } laurent@371: //alert("module wait done"); laurent@371: laurent@371: if (proceed_fn.importDone) laurent@371: proceed_fn.importDone(proceed_fn); laurent@371: else laurent@371: proceed_fn(); laurent@371: } laurent@371: laurent@371: wait(); laurent@371: } laurent@371: """) laurent@371: andrej@1736: andrej@1873: # pylint: disable=old-style-class laurent@371: class Object: andrej@1873: def __init__(self): andrej@1873: pass laurent@371: andrej@1749: laurent@371: object = Object laurent@371: andrej@1736: laurent@371: class Modload: laurent@371: laurent@371: def __init__(self, path, app_modlist, app_imported_fn, dynamic, laurent@371: parent_mod): laurent@371: self.app_modlist = app_modlist laurent@371: self.app_imported_fn = app_imported_fn laurent@371: self.path = path andrej@1752: self.idx = 0 laurent@371: self.dynamic = dynamic laurent@371: self.parent_mod = parent_mod laurent@371: laurent@371: def next(self): andrej@1730: laurent@371: for i in range(len(self.app_modlist[self.idx])): laurent@371: app = self.app_modlist[self.idx][i] andrej@1752: import_module(self.path, self.parent_mod, app, self.dynamic, True) laurent@371: self.idx += 1 laurent@371: laurent@371: if self.idx >= len(self.app_modlist): laurent@371: import_wait(self.app_imported_fn, self.parent_mod, self.dynamic) laurent@371: else: laurent@371: import_wait(getattr(self, "next"), self.parent_mod, self.dynamic) laurent@371: andrej@1736: laurent@371: def get_module(module_name): andrej@1847: _ev = "__mod = %s;" % module_name andrej@1847: JS("pyjs_eval(_ev);") laurent@371: return __mod laurent@371: andrej@1736: laurent@371: def preload_app_modules(path, app_modnames, app_imported_fn, dynamic, laurent@371: parent_mod=None): laurent@371: laurent@371: loader = Modload(path, app_modnames, app_imported_fn, dynamic, parent_mod) laurent@371: loader.next() laurent@371: andrej@1749: andrej@1783: # as comment on line 20 says andrej@1783: # import sys should be below andrej@1859: import sys # noqa # pylint: disable=wrong-import-order,unused-import,wrong-import-position laurent@371: andrej@1736: laurent@371: class BaseException: laurent@371: laurent@371: name = "BaseException" laurent@371: laurent@371: def __init__(self, *args): laurent@371: self.args = args laurent@371: laurent@371: def __str__(self): laurent@371: if len(self.args) is 0: laurent@371: return '' laurent@371: elif len(self.args) is 1: laurent@371: return repr(self.args[0]) laurent@371: return repr(self.args) laurent@371: laurent@371: def toString(self): laurent@371: return str(self) laurent@371: andrej@1736: laurent@371: class Exception(BaseException): laurent@371: name = "Exception" laurent@371: andrej@1736: laurent@371: class TypeError(BaseException): laurent@371: name = "TypeError" laurent@371: andrej@1736: laurent@371: class StandardError(Exception): laurent@371: name = "StandardError" laurent@371: andrej@1736: laurent@371: class LookupError(StandardError): laurent@371: name = "LookupError" laurent@371: laurent@371: def toString(self): laurent@371: return self.name + ": " + self.args[0] laurent@371: andrej@1736: laurent@371: class KeyError(LookupError): laurent@371: name = "KeyError" laurent@371: andrej@1736: laurent@371: class AttributeError(StandardError): laurent@371: name = "AttributeError" laurent@371: laurent@371: def toString(self): laurent@371: return "AttributeError: %s of %s" % (self.args[1], self.args[0]) laurent@371: andrej@1749: laurent@371: JS(""" laurent@371: pyjslib.StopIteration = function () { }; laurent@371: pyjslib.StopIteration.prototype = new Error(); laurent@371: pyjslib.StopIteration.name = 'StopIteration'; laurent@371: pyjslib.StopIteration.message = 'StopIteration'; laurent@371: laurent@371: pyjslib.String_find = function(sub, start, end) { laurent@371: var pos=this.indexOf(sub, start); laurent@371: if (pyjslib.isUndefined(end)) return pos; laurent@371: laurent@371: if (pos + sub.length>end) return -1; laurent@371: return pos; laurent@371: } laurent@371: laurent@371: pyjslib.String_join = function(data) { laurent@371: var text=""; laurent@371: laurent@371: if (pyjslib.isArray(data)) { laurent@371: return data.join(this); laurent@371: } laurent@371: else if (pyjslib.isIteratable(data)) { laurent@371: var iter=data.__iter__(); laurent@371: try { laurent@371: text+=iter.next(); laurent@371: while (true) { laurent@371: var item=iter.next(); laurent@371: text+=this + item; laurent@371: } laurent@371: } laurent@371: catch (e) { laurent@371: if (e != pyjslib.StopIteration) throw e; laurent@371: } laurent@371: } laurent@371: laurent@371: return text; laurent@371: } laurent@371: laurent@371: pyjslib.String_isdigit = function() { laurent@371: return (this.match(/^\d+$/g) != null); laurent@371: } laurent@371: laurent@371: pyjslib.String_replace = function(old, replace, count) { laurent@371: var do_max=false; laurent@371: var start=0; laurent@371: var new_str=""; laurent@371: var pos=0; laurent@371: laurent@371: if (!pyjslib.isString(old)) return this.__replace(old, replace); laurent@371: if (!pyjslib.isUndefined(count)) do_max=true; laurent@371: laurent@371: while (start= s.length) { laurent@371: throw pyjslib.StopIteration; laurent@371: } laurent@371: return s.substring(i++, i, 1); laurent@371: }, laurent@371: '__iter__': function() { laurent@371: return this; laurent@371: } laurent@371: }; laurent@371: } laurent@371: laurent@371: pyjslib.String_strip = function(chars) { laurent@371: return this.lstrip(chars).rstrip(chars); laurent@371: } laurent@371: laurent@371: pyjslib.String_lstrip = function(chars) { laurent@371: if (pyjslib.isUndefined(chars)) return this.replace(/^\s+/, ""); laurent@371: laurent@371: return this.replace(new RegExp("^[" + chars + "]+"), ""); laurent@371: } laurent@371: laurent@371: pyjslib.String_rstrip = function(chars) { laurent@371: if (pyjslib.isUndefined(chars)) return this.replace(/\s+$/, ""); laurent@371: laurent@371: return this.replace(new RegExp("[" + chars + "]+$"), ""); laurent@371: } laurent@371: laurent@371: pyjslib.String_startswith = function(prefix, start) { laurent@371: if (pyjslib.isUndefined(start)) start = 0; laurent@371: laurent@371: if (this.substring(start, prefix.length) == prefix) return true; laurent@371: return false; laurent@371: } laurent@371: laurent@371: pyjslib.abs = Math.abs; laurent@371: laurent@371: """) laurent@371: andrej@1736: laurent@371: class Class: laurent@371: def __init__(self, name): laurent@371: self.name = name laurent@371: laurent@371: def __str___(self): laurent@371: return self.name laurent@371: andrej@1736: andrej@1740: def eq(a, b): laurent@371: JS(""" laurent@371: if (pyjslib.hasattr(a, "__cmp__")) { laurent@371: return a.__cmp__(b) == 0; laurent@371: } else if (pyjslib.hasattr(b, "__cmp__")) { laurent@371: return b.__cmp__(a) == 0; laurent@371: } laurent@371: return a == b; laurent@371: """) laurent@371: andrej@1736: andrej@1740: def cmp(a, b): laurent@371: if hasattr(a, "__cmp__"): laurent@371: return a.__cmp__(b) laurent@371: elif hasattr(b, "__cmp__"): laurent@371: return -b.__cmp__(a) laurent@371: if a > b: laurent@371: return 1 laurent@371: elif b > a: laurent@371: return -1 laurent@371: else: laurent@371: return 0 laurent@371: andrej@1736: laurent@371: def bool(v): laurent@371: # this needs to stay in native code without any dependencies here, laurent@371: # because this is used by if and while, we need to prevent laurent@371: # recursion laurent@371: JS(""" laurent@371: if (!v) return false; laurent@371: switch(typeof v){ laurent@371: case 'boolean': laurent@371: return v; laurent@371: case 'object': laurent@371: if (v.__nonzero__){ laurent@371: return v.__nonzero__(); laurent@371: }else if (v.__len__){ laurent@371: return v.__len__()>0; laurent@371: } laurent@371: return true; laurent@371: } laurent@371: return Boolean(v); laurent@371: """) laurent@371: andrej@1736: laurent@371: class List: laurent@371: def __init__(self, data=None): laurent@371: JS(""" laurent@371: this.l = []; laurent@371: this.extend(data); laurent@371: """) laurent@371: laurent@371: def append(self, item): laurent@371: JS(""" this.l[this.l.length] = item;""") laurent@371: laurent@371: def extend(self, data): laurent@371: JS(""" laurent@371: if (pyjslib.isArray(data)) { laurent@371: n = this.l.length; laurent@371: for (var i=0; i < data.length; i++) { laurent@371: this.l[n+i]=data[i]; laurent@371: } laurent@371: } laurent@371: else if (pyjslib.isIteratable(data)) { laurent@371: var iter=data.__iter__(); laurent@371: var i=this.l.length; laurent@371: try { laurent@371: while (true) { laurent@371: var item=iter.next(); laurent@371: this.l[i++]=item; laurent@371: } laurent@371: } laurent@371: catch (e) { laurent@371: if (e != pyjslib.StopIteration) throw e; laurent@371: } laurent@371: } laurent@371: """) laurent@371: laurent@371: def remove(self, value): laurent@371: JS(""" laurent@371: var index=this.index(value); laurent@371: if (index<0) return false; laurent@371: this.l.splice(index, 1); laurent@371: return true; laurent@371: """) laurent@371: laurent@371: def index(self, value, start=0): laurent@371: JS(""" laurent@371: var length=this.l.length; laurent@371: for (var i=start; i= 0 laurent@371: laurent@371: def __iter__(self): laurent@371: JS(""" laurent@371: var i = 0; laurent@371: var l = this.l; laurent@371: return { laurent@371: 'next': function() { laurent@371: if (i >= l.length) { laurent@371: throw pyjslib.StopIteration; laurent@371: } laurent@371: return l[i++]; laurent@371: }, laurent@371: '__iter__': function() { laurent@371: return this; laurent@371: } laurent@371: }; laurent@371: """) laurent@371: laurent@371: def reverse(self): laurent@371: JS(""" this.l.reverse();""") laurent@371: laurent@371: def sort(self, compareFunc=None, keyFunc=None, reverse=False): laurent@371: if not compareFunc: laurent@371: compareFunc = cmp laurent@371: if keyFunc and reverse: andrej@1740: def thisSort1(a, b): laurent@371: return -compareFunc(keyFunc(a), keyFunc(b)) laurent@371: self.l.sort(thisSort1) laurent@371: elif keyFunc: andrej@1740: def thisSort2(a, b): laurent@371: return compareFunc(keyFunc(a), keyFunc(b)) laurent@371: self.l.sort(thisSort2) laurent@371: elif reverse: andrej@1740: def thisSort3(a, b): laurent@371: return -compareFunc(a, b) laurent@371: self.l.sort(thisSort3) laurent@371: else: laurent@371: self.l.sort(compareFunc) laurent@371: laurent@371: def getArray(self): laurent@371: """ laurent@371: Access the javascript Array that is used internally by this list laurent@371: """ laurent@371: return self.l laurent@371: laurent@371: def __str__(self): laurent@371: return repr(self) laurent@371: andrej@1749: laurent@371: list = List laurent@371: andrej@1736: laurent@371: class Tuple: laurent@371: def __init__(self, data=None): laurent@371: JS(""" laurent@371: this.l = []; laurent@371: this.extend(data); laurent@371: """) laurent@371: laurent@371: def append(self, item): laurent@371: JS(""" this.l[this.l.length] = item;""") laurent@371: laurent@371: def extend(self, data): laurent@371: JS(""" laurent@371: if (pyjslib.isArray(data)) { laurent@371: n = this.l.length; laurent@371: for (var i=0; i < data.length; i++) { laurent@371: this.l[n+i]=data[i]; laurent@371: } laurent@371: } laurent@371: else if (pyjslib.isIteratable(data)) { laurent@371: var iter=data.__iter__(); laurent@371: var i=this.l.length; laurent@371: try { laurent@371: while (true) { laurent@371: var item=iter.next(); laurent@371: this.l[i++]=item; laurent@371: } laurent@371: } laurent@371: catch (e) { laurent@371: if (e != pyjslib.StopIteration) throw e; laurent@371: } laurent@371: } laurent@371: """) laurent@371: laurent@371: def remove(self, value): laurent@371: JS(""" laurent@371: var index=this.index(value); laurent@371: if (index<0) return false; laurent@371: this.l.splice(index, 1); laurent@371: return true; laurent@371: """) laurent@371: laurent@371: def index(self, value, start=0): laurent@371: JS(""" laurent@371: var length=this.l.length; laurent@371: for (var i=start; i= 0 laurent@371: laurent@371: def __iter__(self): laurent@371: JS(""" laurent@371: var i = 0; laurent@371: var l = this.l; laurent@371: return { laurent@371: 'next': function() { laurent@371: if (i >= l.length) { laurent@371: throw pyjslib.StopIteration; laurent@371: } laurent@371: return l[i++]; laurent@371: }, laurent@371: '__iter__': function() { laurent@371: return this; laurent@371: } laurent@371: }; laurent@371: """) laurent@371: laurent@371: def reverse(self): laurent@371: JS(""" this.l.reverse();""") laurent@371: laurent@371: def sort(self, compareFunc=None, keyFunc=None, reverse=False): laurent@371: if not compareFunc: laurent@371: compareFunc = cmp laurent@371: if keyFunc and reverse: andrej@1740: def thisSort1(a, b): laurent@371: return -compareFunc(keyFunc(a), keyFunc(b)) laurent@371: self.l.sort(thisSort1) laurent@371: elif keyFunc: andrej@1740: def thisSort2(a, b): laurent@371: return compareFunc(keyFunc(a), keyFunc(b)) laurent@371: self.l.sort(thisSort2) laurent@371: elif reverse: andrej@1740: def thisSort3(a, b): laurent@371: return -compareFunc(a, b) laurent@371: self.l.sort(thisSort3) laurent@371: else: laurent@371: self.l.sort(compareFunc) laurent@371: laurent@371: def getArray(self): laurent@371: """ laurent@371: Access the javascript Array that is used internally by this list laurent@371: """ laurent@371: return self.l laurent@371: laurent@371: def __str__(self): laurent@371: return repr(self) laurent@371: andrej@1749: laurent@371: tuple = Tuple laurent@371: laurent@371: laurent@371: class Dict: laurent@371: def __init__(self, data=None): laurent@371: JS(""" laurent@371: this.d = {}; laurent@371: laurent@371: if (pyjslib.isArray(data)) { laurent@371: for (var i in data) { laurent@371: var item=data[i]; laurent@371: this.__setitem__(item[0], item[1]); laurent@371: //var sKey=pyjslib.hash(item[0]); laurent@371: //this.d[sKey]=item[1]; laurent@371: } laurent@371: } laurent@371: else if (pyjslib.isIteratable(data)) { laurent@371: var iter=data.__iter__(); laurent@371: try { laurent@371: while (true) { laurent@371: var item=iter.next(); laurent@371: this.__setitem__(item.__getitem__(0), item.__getitem__(1)); laurent@371: } laurent@371: } laurent@371: catch (e) { laurent@371: if (e != pyjslib.StopIteration) throw e; laurent@371: } laurent@371: } laurent@371: else if (pyjslib.isObject(data)) { laurent@371: for (var key in data) { laurent@371: this.__setitem__(key, data[key]); laurent@371: } laurent@371: } laurent@371: """) laurent@371: laurent@371: def __setitem__(self, key, value): laurent@371: JS(""" laurent@371: var sKey = pyjslib.hash(key); laurent@371: this.d[sKey]=[key, value]; laurent@371: """) laurent@371: laurent@371: def __getitem__(self, key): laurent@371: JS(""" laurent@371: var sKey = pyjslib.hash(key); laurent@371: var value=this.d[sKey]; laurent@371: if (pyjslib.isUndefined(value)){ laurent@371: throw pyjslib.KeyError(key); laurent@371: } laurent@371: return value[1]; laurent@371: """) laurent@371: laurent@371: def __nonzero__(self): laurent@371: JS(""" laurent@371: for (var i in this.d){ laurent@371: return true; laurent@371: } laurent@371: return false; laurent@371: """) laurent@371: laurent@371: def __len__(self): laurent@371: JS(""" laurent@371: var size=0; laurent@371: for (var i in this.d) size++; laurent@371: return size; laurent@371: """) laurent@371: laurent@371: def has_key(self, key): laurent@371: return self.__contains__(key) laurent@371: laurent@371: def __delitem__(self, key): laurent@371: JS(""" laurent@371: var sKey = pyjslib.hash(key); laurent@371: delete this.d[sKey]; laurent@371: """) laurent@371: laurent@371: def __contains__(self, key): laurent@371: JS(""" laurent@371: var sKey = pyjslib.hash(key); laurent@371: return (pyjslib.isUndefined(this.d[sKey])) ? false : true; laurent@371: """) laurent@371: laurent@371: def keys(self): laurent@371: JS(""" laurent@371: var keys=new pyjslib.List(); laurent@371: for (var key in this.d) { laurent@371: keys.append(this.d[key][0]); laurent@371: } laurent@371: return keys; laurent@371: """) laurent@371: laurent@371: def values(self): laurent@371: JS(""" laurent@371: var values=new pyjslib.List(); laurent@371: for (var key in this.d) values.append(this.d[key][1]); laurent@371: return values; laurent@371: """) laurent@371: laurent@371: def items(self): laurent@371: JS(""" laurent@371: var items = new pyjslib.List(); laurent@371: for (var key in this.d) { laurent@371: var kv = this.d[key]; laurent@371: items.append(new pyjslib.List(kv)) laurent@371: } laurent@371: return items; laurent@371: """) laurent@371: laurent@371: def __iter__(self): laurent@371: return self.keys().__iter__() laurent@371: laurent@371: def iterkeys(self): laurent@371: return self.__iter__() laurent@371: laurent@371: def itervalues(self): andrej@1752: return self.values().__iter__() laurent@371: laurent@371: def iteritems(self): andrej@1752: return self.items().__iter__() laurent@371: laurent@371: def setdefault(self, key, default_value): andrej@1775: if key not in self: laurent@371: self[key] = default_value laurent@371: laurent@371: def get(self, key, default_=None): andrej@1775: if key not in self: laurent@371: return default_ laurent@371: return self[key] laurent@371: laurent@371: def update(self, d): andrej@1740: for k, v in d.iteritems(): laurent@371: self[k] = v laurent@371: laurent@371: def getObject(self): laurent@371: """ laurent@371: Return the javascript Object which this class uses to store laurent@371: dictionary keys and values laurent@371: """ laurent@371: return self.d laurent@371: laurent@371: def copy(self): laurent@371: return Dict(self.items()) laurent@371: laurent@371: def __str__(self): laurent@371: return repr(self) laurent@371: andrej@1749: laurent@371: dict = Dict laurent@371: laurent@371: # taken from mochikit: range( [start,] stop[, step] ) andrej@1736: andrej@1736: laurent@371: def range(): laurent@371: JS(""" laurent@371: var start = 0; laurent@371: var stop = 0; laurent@371: var step = 1; laurent@371: laurent@371: if (arguments.length == 2) { laurent@371: start = arguments[0]; laurent@371: stop = arguments[1]; laurent@371: } laurent@371: else if (arguments.length == 3) { laurent@371: start = arguments[0]; laurent@371: stop = arguments[1]; laurent@371: step = arguments[2]; laurent@371: } laurent@371: else if (arguments.length>0) stop = arguments[0]; laurent@371: laurent@371: return { laurent@371: 'next': function() { laurent@371: if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) throw pyjslib.StopIteration; laurent@371: var rval = start; laurent@371: start += step; laurent@371: return rval; laurent@371: }, laurent@371: '__iter__': function() { laurent@371: return this; laurent@371: } laurent@371: } laurent@371: """) laurent@371: andrej@1736: laurent@371: def slice(object, lower, upper): laurent@371: JS(""" laurent@371: if (pyjslib.isString(object)) { laurent@371: if (lower < 0) { laurent@371: lower = object.length + lower; laurent@371: } laurent@371: if (upper < 0) { laurent@371: upper = object.length + upper; laurent@371: } laurent@371: if (pyjslib.isNull(upper)) upper=object.length; laurent@371: return object.substring(lower, upper); laurent@371: } laurent@371: if (pyjslib.isObject(object) && object.slice) laurent@371: return object.slice(lower, upper); laurent@371: laurent@371: return null; laurent@371: """) laurent@371: andrej@1736: laurent@371: def str(text): laurent@371: JS(""" laurent@371: if (pyjslib.hasattr(text,"__str__")) { laurent@371: return text.__str__(); laurent@371: } laurent@371: return String(text); laurent@371: """) laurent@371: andrej@1736: laurent@371: def ord(x): andrej@1828: if isString(x) and len(x) is 1: laurent@371: JS(""" laurent@371: return x.charCodeAt(0); laurent@371: """) laurent@371: else: laurent@371: JS(""" laurent@371: throw pyjslib.TypeError(); laurent@371: """) laurent@371: return None laurent@371: andrej@1736: laurent@371: def chr(x): laurent@371: JS(""" laurent@371: return String.fromCharCode(x) laurent@371: """) laurent@371: andrej@1736: laurent@371: def is_basetype(x): laurent@371: JS(""" laurent@371: var t = typeof(x); laurent@371: return t == 'boolean' || laurent@371: t == 'function' || laurent@371: t == 'number' || laurent@371: t == 'string' || laurent@371: t == 'undefined' laurent@371: ; laurent@371: """) laurent@371: andrej@1736: laurent@371: def get_pyjs_classtype(x): laurent@371: JS(""" laurent@371: if (pyjslib.hasattr(x, "__class__")) laurent@371: if (pyjslib.hasattr(x.__class__, "__new__")) laurent@371: var src = x.__class__.__name__; laurent@371: return src; laurent@371: return null; laurent@371: """) laurent@371: andrej@1736: laurent@371: def repr(x): laurent@371: """ Return the string representation of 'x'. laurent@371: """ laurent@371: JS(""" laurent@371: if (x === null) laurent@371: return "null"; laurent@371: laurent@371: if (x === undefined) laurent@371: return "undefined"; laurent@371: laurent@371: var t = typeof(x); laurent@371: laurent@371: //alert("repr typeof " + t + " : " + x); laurent@371: laurent@371: if (t == "boolean") laurent@371: return x.toString(); laurent@371: laurent@371: if (t == "function") laurent@371: return ""; laurent@371: laurent@371: if (t == "number") laurent@371: return x.toString(); laurent@371: laurent@371: if (t == "string") { laurent@371: if (x.indexOf("'") == -1) laurent@371: return "'" + x + "'"; laurent@371: if (x.indexOf('"') == -1) laurent@371: return '"' + x + '"'; laurent@371: var s = x.replace(new RegExp('"', "g"), '\\\\"'); laurent@371: return '"' + s + '"'; laurent@371: }; laurent@371: laurent@371: if (t == "undefined") laurent@371: return "undefined"; laurent@371: laurent@371: // If we get here, x is an object. See if it's a Pyjamas class. laurent@371: laurent@371: if (!pyjslib.hasattr(x, "__init__")) laurent@371: return "<" + x.toString() + ">"; laurent@371: laurent@371: // Handle the common Pyjamas data types. laurent@371: laurent@371: var constructor = "UNKNOWN"; laurent@371: laurent@371: constructor = pyjslib.get_pyjs_classtype(x); laurent@371: laurent@371: //alert("repr constructor: " + constructor); laurent@371: laurent@371: if (constructor == "Tuple") { laurent@371: var contents = x.getArray(); laurent@371: var s = "("; laurent@371: for (var i=0; i < contents.length; i++) { laurent@371: s += pyjslib.repr(contents[i]); laurent@371: if (i < contents.length - 1) laurent@371: s += ", "; laurent@371: }; laurent@371: s += ")" laurent@371: return s; laurent@371: }; laurent@371: laurent@371: if (constructor == "List") { laurent@371: var contents = x.getArray(); laurent@371: var s = "["; laurent@371: for (var i=0; i < contents.length; i++) { laurent@371: s += pyjslib.repr(contents[i]); laurent@371: if (i < contents.length - 1) laurent@371: s += ", "; laurent@371: }; laurent@371: s += "]" laurent@371: return s; laurent@371: }; laurent@371: laurent@371: if (constructor == "Dict") { laurent@371: var keys = new Array(); laurent@371: for (var key in x.d) laurent@371: keys.push(key); laurent@371: laurent@371: var s = "{"; laurent@371: for (var i=0; i return the class name. laurent@371: // Note that we replace underscores with dots so that the name will laurent@371: // (hopefully!) look like the original Python name. laurent@371: laurent@371: //var s = constructor.replace(new RegExp('_', "g"), '.'); laurent@371: return "<" + constructor + " object>"; laurent@371: """) laurent@371: andrej@1736: laurent@371: def float(text): laurent@371: JS(""" laurent@371: return parseFloat(text); laurent@371: """) laurent@371: andrej@1736: laurent@371: def int(text, radix=0): laurent@371: JS(""" laurent@371: return parseInt(text, radix); laurent@371: """) laurent@371: andrej@1736: laurent@371: def len(object): laurent@371: JS(""" laurent@371: if (object==null) return 0; laurent@371: if (pyjslib.isObject(object) && object.__len__) return object.__len__(); laurent@371: return object.length; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isinstance(object_, classinfo): laurent@371: if pyjslib.isUndefined(object_): laurent@371: return False laurent@371: if not pyjslib.isObject(object_): andrej@1730: laurent@371: return False laurent@371: if _isinstance(classinfo, Tuple): laurent@371: for ci in classinfo: laurent@371: if isinstance(object_, ci): laurent@371: return True laurent@371: return False laurent@371: else: laurent@371: return _isinstance(object_, classinfo) laurent@371: andrej@1736: laurent@371: def _isinstance(object_, classinfo): laurent@371: if not pyjslib.isObject(object_): laurent@371: return False laurent@371: JS(""" laurent@371: if (object_.__class__){ laurent@371: var res = object_ instanceof classinfo.constructor; laurent@371: return res; laurent@371: } laurent@371: return false; laurent@371: """) laurent@371: andrej@1736: andrej@1865: def getattr(obj, name, default_=None): laurent@371: JS(""" laurent@371: if ((!pyjslib.isObject(obj))||(pyjslib.isUndefined(obj[name]))){ laurent@371: if (pyjslib.isUndefined(default_)){ laurent@371: throw pyjslib.AttributeError(obj, name); laurent@371: }else{ laurent@371: return default_; laurent@371: } laurent@371: } laurent@371: if (!pyjslib.isFunction(obj[name])) return obj[name]; laurent@371: var fnwrap = function() { laurent@371: var args = []; laurent@371: for (var i = 0; i < arguments.length; i++) { laurent@371: args.push(arguments[i]); laurent@371: } laurent@371: return obj[name].apply(obj,args); laurent@371: } laurent@371: fnwrap.__name__ = name; laurent@371: return fnwrap; laurent@371: """) laurent@371: andrej@1736: laurent@371: def setattr(obj, name, value): laurent@371: JS(""" laurent@371: if (!pyjslib.isObject(obj)) return null; laurent@371: laurent@371: obj[name] = value; laurent@371: laurent@371: """) laurent@371: andrej@1736: laurent@371: def hasattr(obj, name): laurent@371: JS(""" laurent@371: if (!pyjslib.isObject(obj)) return false; laurent@371: if (pyjslib.isUndefined(obj[name])) return false; laurent@371: laurent@371: return true; laurent@371: """) laurent@371: andrej@1736: laurent@371: def dir(obj): laurent@371: JS(""" laurent@371: var properties=new pyjslib.List(); laurent@371: for (property in obj) properties.append(property); laurent@371: return properties; laurent@371: """) laurent@371: andrej@1736: laurent@371: def filter(obj, method, sequence=None): laurent@371: # object context is LOST when a method is passed, hence object must be passed separately laurent@371: # to emulate python behaviour, should generate this code inline rather than as a function call laurent@371: items = [] laurent@371: if sequence is None: laurent@371: sequence = method laurent@371: method = obj laurent@371: laurent@371: for item in sequence: laurent@371: if method(item): laurent@371: items.append(item) laurent@371: else: laurent@371: for item in sequence: laurent@371: if method.call(obj, item): laurent@371: items.append(item) laurent@371: laurent@371: return items laurent@371: laurent@371: laurent@371: def map(obj, method, sequence=None): laurent@371: items = [] laurent@371: laurent@371: if sequence is None: laurent@371: sequence = method laurent@371: method = obj laurent@371: laurent@371: for item in sequence: laurent@371: items.append(method(item)) laurent@371: else: laurent@371: for item in sequence: laurent@371: items.append(method.call(obj, item)) laurent@371: laurent@371: return items laurent@371: laurent@371: laurent@371: def enumerate(sequence): laurent@371: enumeration = [] laurent@371: nextIndex = 0 laurent@371: for item in sequence: laurent@371: enumeration.append([nextIndex, item]) laurent@371: nextIndex = nextIndex + 1 laurent@371: return enumeration laurent@371: laurent@371: laurent@371: def min(*sequence): laurent@371: minValue = None laurent@371: for item in sequence: laurent@371: if minValue is None: laurent@371: minValue = item laurent@371: elif item < minValue: laurent@371: minValue = item laurent@371: return minValue laurent@371: laurent@371: laurent@371: def max(*sequence): laurent@371: maxValue = None laurent@371: for item in sequence: laurent@371: if maxValue is None: laurent@371: maxValue = item laurent@371: elif item > maxValue: laurent@371: maxValue = item laurent@371: return maxValue laurent@371: laurent@371: laurent@371: next_hash_id = 0 laurent@371: andrej@1736: laurent@371: def hash(obj): laurent@371: JS(""" laurent@371: if (obj == null) return null; laurent@371: laurent@371: if (obj.$H) return obj.$H; laurent@371: if (obj.__hash__) return obj.__hash__(); laurent@371: if (obj.constructor == String || obj.constructor == Number || obj.constructor == Date) return obj; laurent@371: laurent@371: obj.$H = ++pyjslib.next_hash_id; laurent@371: return obj.$H; laurent@371: """) laurent@371: laurent@371: laurent@371: # type functions from Douglas Crockford's Remedial Javascript: http://www.crockford.com/javascript/remedial.html laurent@371: def isObject(a): laurent@371: JS(""" laurent@371: return (a != null && (typeof a == 'object')) || pyjslib.isFunction(a); laurent@371: """) laurent@371: andrej@1736: laurent@371: def isFunction(a): laurent@371: JS(""" laurent@371: return typeof a == 'function'; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isString(a): laurent@371: JS(""" laurent@371: return typeof a == 'string'; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isNull(a): laurent@371: JS(""" laurent@371: return typeof a == 'object' && !a; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isArray(a): laurent@371: JS(""" laurent@371: return pyjslib.isObject(a) && a.constructor == Array; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isUndefined(a): laurent@371: JS(""" laurent@371: return typeof a == 'undefined'; laurent@371: """) laurent@371: andrej@1736: laurent@371: def isIteratable(a): laurent@371: JS(""" laurent@371: return pyjslib.isString(a) || (pyjslib.isObject(a) && a.__iter__); laurent@371: """) laurent@371: andrej@1736: laurent@371: def isNumber(a): laurent@371: JS(""" laurent@371: return typeof a == 'number' && isFinite(a); laurent@371: """) laurent@371: andrej@1736: laurent@371: def toJSObjects(x): laurent@371: """ laurent@371: Convert the pyjs pythonic List and Dict objects into javascript Object and Array laurent@371: objects, recursively. laurent@371: """ laurent@371: if isArray(x): laurent@371: JS(""" laurent@371: var result = []; laurent@371: for(var k=0; k < x.length; k++) { laurent@371: var v = x[k]; laurent@371: var tv = pyjslib.toJSObjects(v); laurent@371: result.push(tv); laurent@371: } laurent@371: return result; laurent@371: """) laurent@371: if isObject(x): laurent@371: if isinstance(x, Dict): laurent@371: JS(""" laurent@371: var o = x.getObject(); laurent@371: var result = {}; laurent@371: for (var i in o) { laurent@371: result[o[i][0].toString()] = o[i][1]; laurent@371: } laurent@371: return pyjslib.toJSObjects(result) laurent@371: """) laurent@371: elif isinstance(x, List): laurent@371: return toJSObjects(x.l) laurent@371: elif hasattr(x, '__class__'): laurent@371: # we do not have a special implementation for custom laurent@371: # classes, just pass it on laurent@371: return x laurent@371: if isObject(x): laurent@371: JS(""" laurent@371: var result = {}; laurent@371: for(var k in x) { laurent@371: var v = x[k]; laurent@371: var tv = pyjslib.toJSObjects(v) laurent@371: result[k] = tv; laurent@371: } laurent@371: return result; laurent@371: """) laurent@371: return x laurent@371: andrej@1736: laurent@371: def printFunc(objs): laurent@371: JS(""" laurent@371: if ($wnd.console==undefined) return; laurent@371: var s = ""; laurent@371: for(var i=0; i < objs.length; i++) { laurent@371: if(s != "") s += " "; laurent@371: s += objs[i]; laurent@371: } laurent@371: console.debug(s) laurent@371: """) laurent@371: andrej@1736: laurent@371: def type(clsname, bases=None, methods=None): laurent@371: """ creates a class, derived from bases, with methods and variables laurent@371: """ laurent@371: laurent@371: JS(" var mths = {}; ") laurent@371: if methods: laurent@371: for k in methods.keys(): andrej@1847: _mth = methods[k] andrej@1847: JS(" mths[k] = _mth; ") laurent@371: laurent@371: JS(" var bss = null; ") laurent@371: if bases: laurent@371: JS("bss = bases.l;") laurent@371: JS(" return pyjs_type(clsname, bss, mths); ")