diff options
Diffstat (limited to 'lib/js/urweb.js')
-rw-r--r-- | lib/js/urweb.js | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js index de956d3f..5ff5b9fb 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -18,6 +18,9 @@ function remove(x, ls) { function union(ls1, ls2) { return (ls1 ? (member(ls1.data, ls2) ? union(ls1.next, ls2) : cons(ls1.data, union(ls1.next, ls2))) : ls2); } +function length(ls) { + return (ls ? 1 + length(ls.next) : 0); +} // Embedding closures in XML strings @@ -38,29 +41,40 @@ function cat(s1, s2) { } var closures = []; +var freeClosures = null; function newClosure(f) { - var n = closures.length; + var n; + if (freeClosures == null) { + n = closures.length; + } else { + n = freeClosures.data; + freeClosures = freeClosures.next; + } closures[n] = f; return n; } +function freeClosure(n) { + closures[n] = null; + freeClosures = cons(n, freeClosures); +} + function cr(n) { return closures[n](); } -function flatten(tr) { +function flatten(cls, tr) { if (tr.cat1 != null) - return flatten(tr.cat1) + flatten(tr.cat2); - else if (tr.closure != null) - return "cr(" + newClosure(tr.closure) + ")"; - else + return flatten(cls, tr.cat1) + flatten(cls, tr.cat2); + else if (tr.closure != null) { + var cl = newClosure(tr.closure); + cls.v = cons(cl, cls.v); + return "cr(" + cl + ")"; + } else return tr; } -function clearClosures() { - closures = []; -} // Dynamic tree management @@ -154,8 +168,10 @@ function dyn(s) { x.dead = false; x.signal = s; x.sources = null; + x.closures = null; x.recreate = function(v) { - ++dynDepth; + for (var ls = x.closures; ls; ls = ls.next) + freeClosure(ls.data); var spans = x.getElementsByTagName("span"); for (var i = 0; i < spans.length; ++i) { @@ -163,16 +179,17 @@ function dyn(s) { span.dead = true; for (var ls = span.sources; ls; ls = ls.next) ls.data.dyns = remove(span, ls.data.dyns); + for (var ls = span.closures; ls; ls = ls.next) + freeClosure(ls.data); } - x.innerHTML = flatten(v); + var cls = {v : null}; + x.innerHTML = flatten(cls, v); + x.closures = cls.v; runScripts(x); - - if (--dynDepth == 0) - clearClosures(); }; - populate(x); addNode(x); + populate(x); } function inp(t, s) { @@ -236,7 +253,7 @@ function pf() { // Remote calls -var client_id = 0; +var client_id = null; var client_pass = 0; var url_prefix = "/"; var timeout = 60; @@ -261,7 +278,7 @@ function getXHR(uri) function requestUri(xhr, uri) { xhr.open("GET", uri, true); - if (client_id != 0) { + if (client_id != null) { xhr.setRequestHeader("UrWeb-Client", client_id.toString()); xhr.setRequestHeader("UrWeb-Pass", client_pass.toString()); } @@ -270,6 +287,11 @@ function requestUri(xhr, uri) { } function rc(uri, parse, k) { + var cls = {v : null}; + uri = flatten(cls, uri); + for (cl = cls.v; cl != null; cl = cl.next) + freeClosure(cl.data); + var xhr = getXHR(); xhr.onreadystatechange = function() { |