changeset 1538:ade93cd5bc59

Fix bug with <dyn> as first child of <table>
author Adam Chlipala <adam@chlipala.net>
date Sun, 14 Aug 2011 17:39:18 -0400
parents e627bab3eda7
children dde3bd82cb3d
files lib/js/urweb.js tests/dynTable.ur
diffstat 2 files changed, 54 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/lib/js/urweb.js	Sun Aug 14 16:46:36 2011 -0400
+++ b/lib/js/urweb.js	Sun Aug 14 17:39:18 2011 -0400
@@ -385,6 +385,37 @@
         freeClosure(ls.data);
 }
 
+// Sometimes we wind up with tables that contain <script>s outside the single <tbody>.
+// To avoid dealing with that case, we normalize by moving <script>s into <tbody>.
+function normalizeTable(table) {
+    var orig = table;
+
+    var script, next;
+
+    while (table.tagName != "TABLE")
+        table = table.parentNode;
+
+    for (var tbody = table.firstChild; tbody; tbody = tbody.nextSibling) {
+        if (tbody.tagName == "TBODY") {
+            for (script = table.firstChild; script && script != tbody; script = next) {
+                next = script.nextSibling;
+
+                tbody.insertBefore(script, tbody.firstChild);
+            }
+
+            return;
+        }
+    }
+
+    var tbody = document.createElement("tbody");
+    for (script = table.firstChild; script; script = next) {
+        next = script.nextSibling;
+        
+        tbody.insertBefore(script, tbody.firstChild);
+    }
+    table.appendChild(tbody);
+}
+
 function dyn(pnode, s) {
     var x = document.createElement("script");
     x.dead = false;
@@ -420,6 +451,8 @@
         x.closures = cls.v;
 
         if (pnode == "table") {
+            normalizeTable(x.parentNode);
+
             var dummy = document.createElement("body");
             dummy.innerHTML = "<table>" + html + "</table>";
             runScripts(dummy);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/dynTable.ur	Sun Aug 14 17:39:18 2011 -0400
@@ -0,0 +1,21 @@
+fun main () : transaction page =
+    s <- source <xml/>;
+    s1 <- source <xml/>;
+    n <- source 0;
+    return <xml><body>
+      <table>
+        <dyn signal={signal s}/>
+        <tr> <td>Hi</td> </tr>
+      </table>
+
+      <button onclick={v <- get n;
+                       set n (v + 1);
+                       set s <xml><tr> <td>Whoa!({[v]})</td> </tr></xml>}/>
+
+      <table>
+        <tr> <dyn signal={signal s1}/> </tr>
+        <tr> <td>Hi!</td> </tr>
+      </table>
+
+      <button onclick={set s1 <xml><td>Whoa!</td></xml>}/>
+    </body></xml>