#
# Warning: this is an alpha module and might be removed/renamed in
# later pyjamas versions
#
from __pyjamas__ import wnd,doc,JS,setCompilerOptions
from __javascript__ import ActiveXObject,XMLHttpRequest
from pyjamas import DOM
from __pyjamas__ import debugger
import sys
setCompilerOptions("noSourceTracking", "noLineTracking", "noStoreSource")
class AjaxError(RuntimeError):
pass
def createHttpRequest():
if JS("""typeof $wnd.XMLHttpRequest != 'undefined'"""):
# IE7+, Mozilla, Safari, ...
return JS("""new XMLHttpRequest()""")
# Check for IE6/ActiveX
try:
res = JS("""new ActiveXObject("Msxml2.XMLHTTP")""")
return res
except:
pass
return None
#
# load(url)
#
# @param url URL to load
# @param onreadystatechange function to be used for onreadystatechange
# @param on_load_fn function to be called on succes, with parameters event, request
# @param async request mode
# @returns async == False: request object, async == True: None
#
def load(url, onreadystatechange=None, on_load_fn=None, async=False):
setCompilerOptions("noDebug")
wnd().status = ('Loading ' + url)
req = createHttpRequest()
if onreadystatechange is None:
def onreadystatechange(evnt):
if req.readyState==4 and (req.status == 200 or req.status == 0):
str = req.responseText
wnd().status = ('Loaded ' + url)
if not on_load_fn is None:
on_load_fn(evnt, req)
# next line is in JS() for IE6
JS("req.onreadystatechange = onreadystatechange;")
req.open("GET", url , async)
try:
req.send(None)
if async:
return None
while True:
if ( req.status == 200
or (req.status == 0 and req.responseText)
):
if not on_load_fn is None:
on_load_fn(None, req)
return req
if req.status != 0 or req.responseText != "":
break
except:
pass
raise AjaxError("Synchronous error", req.status)
def inject(values, namespace = None, names=None):
if namespace is None:
from __pyjamas__ import JS
namespace = JS("$pyjs.global_namespace")
values = dict(values)
if names is None:
for k in values:
v = values[k]
JS("""namespace[k] = v;""")
else:
for k in names:
v = values[k]
JS("""namespace[k] = v;""")
#
# activate_css(str)
#
# looks for any < link > in the input and sets up a corresponding link node
# in the main document.
#
def activate_css(targetnode):
scriptnodes = list(targetnode.getElementsByTagName('link'))
for LC in range(len(scriptnodes)):
sn = scriptnodes[LC]
sn.parentNode.removeChild(sn)
fileref = DOM.createElement('link')
if hassattr(sn, "href"):
fileref.href = sn.href
else:
fileref.text = sn.text
fileref.rel = "stylesheet"
fileref.type = "text/css"
doc().getElementsByTagName("head").item(0).appendChild(fileref)
#
# activate_javascript(str)
#
# looks for any < script > in the input text and sets up a corresponding
# script node in the main document.
#
def activate_javascript(txt):
fileref = DOM.createElement('script')
fileref.text = txt
fileref.type = "text/javascript"
fileref.language = "javascript"
#fileref.defer = True
#debug = DOM.createElement('pre')
#debug.innerHTML = 'test'
#debug.innerHTML += "href:" + sn.src + " text:" + fileref.text
#var bodyels = doc().getElementsByTagName("body")
#bodyels[bodyels.length-1].appendChild(debug)
fileref = fileref.cloneNode(True)
doc().getElementsByTagName("head").item(0).appendChild(fileref)
def eval(str):
from __javascript__ import eval
return eval(str)
#
# ajax_eval(url)
#
# @param url load and activate url
# @returns readyState
#
def ajax_eval(url, on_load_fn, async):
setCompilerOptions("noDebug")
def onready(evnt, req):
str = req.responseText
activate_javascript(str)
if not on_load_fn is None:
on_load_fn()
load(url, None, onready, async)
__imported__ = {}
def ajax_import(url, namespace=None, names=None):
setCompilerOptions("noDebug")
if __imported__.has_key(url):
module = __imported__[url]
else:
req = load(url, None, None, False)
module = None
name_getter = []
if names is None:
names = []
for name in names:
name_getter.append("$pyjs$moduleObject['%s'] = %s;" % (name, name))
script = """(function ( ) {
$pyjs$moduleObject={};
%s;
%s
return $pyjs$moduleObject;
})();""" % (req.responseText, "\n".join(name_getter))
try:
module = eval(script)
except:
e = sys.exc_info()
raise AjaxError("Error in %s: %s" % (url, e.message))
__imported__[url] = module
inject(module, namespace, names)
# From here, just converted from dynamicajax.js
#
# pyjs_load_script
#
# @param url load script url
# @param module module name
# @param onload text of function to be eval/executed on successful load
#
def load_script(url, onload, async):
wnd().status = ('Loading ' + url)
def onload_fn():
wnd.status = ('Loaded ' + url)
if not onload is None:
eval(onload)
return True
e = DOM.createElement("script")
e.src = url
e.type="text/javascript"
e.language = "javascript"
e.defer = async
e.onload = onload_fn
doc().getElementsByTagName("head")[0].appendChild(e)
#
# ajax_dlink_refresh(oj,url)
#
# @param id id of element for insert
# @param url load url
# @param timeout refresh timeout period, ms
# @returns readyState
#
# use these to overrun an existing timeout, so that
# we don't end up with several of them!
running_timeout = 0
timeout_idname = None
timeout_url = None
timeout_on_load_fn = None
redo_timeout = None
timeout_id = None
def ajax_dlink_refresh(idname, url, on_load_fn, timeout):
global running_timeout, timeout_idname, timeout_url, timeout_on_load_fn, redo_timeout, timeout_id
timeout_idname = idname
timeout_url = url
timeout_on_load_fn = on_load_fn
redo_timeout = timeout
if running_timeout > 0:
return
# FIXME: should use pyjamas.Timer.Timer
from __javascript__ import setTimeout
timeout_id = setTimeout(do_ajax_dlink_refresh, timeout)
running_timeout = 1
def do_ajax_dlink_refresh():
global running_timeout, timeout_id
if ajax_dlink(timeout_idname, timeout_url, timeout_on_load_fn) == 0:
timeout_id = None
running_timeout = 0
return
timeout_id = None
running_timeout = 0
ajax_dlink_refresh(timeout_idname, timeout_url, timeout_on_load_fn,
redo_timeout)
#
# ajax_dlink(oj,url)
#
# @param id id of element for insert
# @param url load url
# @returns readyState
#
def ajax_dlink(idname, url, on_load_fn):
global running_timeout, timeout_idname, timeout_url, timeout_on_load_fn, redo_timeout, timeout_id
from __pyjamas__ import doc
body = doc().body
from __javascript__ import clearTimeout
if timeout_id:
clearTimeout(timeout_id) # really important - get into a mess otherwise
def onreadystatechange():
if xhtoj.readyState == 4:
jsnode = 0
if xhtoj.status == 200:
txt = xhtoj.responseText
jsnode = None
if idname:
jsnode = DOM.getElementById(idname)
if jsnode is None:
jsnode = DOM.createElement('script')
#tst = DOM.createElement('html')
#tst.innerHTML = str
activate_javascript(txt)
if not on_load_fn is None:
wnd().alert(on_load_fn)
# eval(on_load_fn)
test_fn()
return 1
else:
jsnode = DOM.getElementById(idname)
if not jsnode is None:
jsnode.innerHTML = xhtoj.status
xhtoj = createHttpRequest()
xhtoj.onreadystatechange = onreadystatechange
xhtoj.open("GET", url , True )
xhtoj.send("")
return 0
|