aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2011-08-14 17:39:18 -0400
committerGravatar Adam Chlipala <adam@chlipala.net>2011-08-14 17:39:18 -0400
commitc58370c7b4a4cc6027baf7b6ebfcc1dcab181666 (patch)
treee5943aaf8f088e60d96a4c87d7228ec3c62c9593
parent882b016302da2645ff07ccaf9c78eaa60f736461 (diff)
Fix bug with <dyn> as first child of <table>
-rw-r--r--lib/js/urweb.js33
-rw-r--r--tests/dynTable.ur21
2 files changed, 54 insertions, 0 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js
index 6343543e..77fc5d79 100644
--- a/lib/js/urweb.js
+++ b/lib/js/urweb.js
@@ -385,6 +385,37 @@ function killScript(scr) {
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 @@ function dyn(pnode, s) {
x.closures = cls.v;
if (pnode == "table") {
+ normalizeTable(x.parentNode);
+
var dummy = document.createElement("body");
dummy.innerHTML = "<table>" + html + "</table>";
runScripts(dummy);
diff --git a/tests/dynTable.ur b/tests/dynTable.ur
new file mode 100644
index 00000000..7fe295c6
--- /dev/null
+++ b/tests/dynTable.ur
@@ -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>