diff lib/js/urweb.js @ 703:a5d8b470d7ca

Fixing some regressions and other bugs
author Adam Chlipala <adamc@hcoop.net>
date Sun, 05 Apr 2009 16:17:32 -0400
parents 655bcc9b77e0
children 6fc633d990e7
line wrap: on
line diff
--- a/lib/js/urweb.js	Sun Apr 05 12:41:41 2009 -0400
+++ b/lib/js/urweb.js	Sun Apr 05 16:17:32 2009 -0400
@@ -18,6 +18,9 @@
 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 @@
 }
 
 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 @@
   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 @@
       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();
   };
+  addNode(x);
   populate(x);
-  addNode(x);
 }
 
 function inp(t, s) {
@@ -236,7 +253,7 @@
 
 // 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 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 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() {