diff options
author | Adam Chlipala <adam@chlipala.net> | 2011-08-14 17:39:18 -0400 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2011-08-14 17:39:18 -0400 |
commit | c58370c7b4a4cc6027baf7b6ebfcc1dcab181666 (patch) | |
tree | e5943aaf8f088e60d96a4c87d7228ec3c62c9593 | |
parent | 882b016302da2645ff07ccaf9c78eaa60f736461 (diff) |
Fix bug with <dyn> as first child of <table>
-rw-r--r-- | lib/js/urweb.js | 33 | ||||
-rw-r--r-- | tests/dynTable.ur | 21 |
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> |