Mercurial > urweb
changeset 1803:d2383ffc18ab
Back out last change and pursue a different fix, based on explicitly aborting script execution at times when we don't expect scripts to run
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Fri, 03 Aug 2012 12:39:04 -0400 |
parents | e3ec868567ce |
children | 62c18ecbfec4 |
files | lib/js/urweb.js tests/babySpawn.ur tests/dynTable.ur |
diffstat | 3 files changed, 94 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/js/urweb.js Fri Aug 03 08:38:47 2012 -0400 +++ b/lib/js/urweb.js Fri Aug 03 12:39:04 2012 -0400 @@ -691,6 +691,8 @@ return pos; } +var thisScript = null; + function parent() { return thisScript ? thisScript.parentNode : lastParent(); } @@ -703,10 +705,21 @@ lastParent().appendChild(node); } -var thisScript = null; +function runScripts(node) { + if (node.tagName == "SCRIPT") { + var savedScript = thisScript; + thisScript = node; + + try { + eval(thisScript.text); + } catch (v) { + doExn(v); + } + if (thisScript.parentNode) + thisScript.parentNode.removeChild(thisScript); -function runScripts(node) { - if (node.getElementsByTagName) { + thisScript = savedScript; + } else if (node.getElementsByTagName) { var savedScript = thisScript; var scripts = node.getElementsByTagName("script"), scriptsCopy = []; @@ -747,7 +760,7 @@ var script, next; - while (table.tagName != "TABLE") + while (table && table.tagName != "TABLE") table = table.parentNode; for (var tbody = table.firstChild; tbody; tbody = tbody.nextSibling) { @@ -776,7 +789,12 @@ table.appendChild(tbody); } +var suspendScripts = false; + function dyn(pnode, s) { + if (suspendScripts) + return; + var x = document.createElement("script"); x.dead = false; x.signal = s; @@ -814,8 +832,14 @@ normalizeTable(x.parentNode); var dummy = document.createElement("body"); - dummy.innerHTML = "<table>" + html + "</table>"; - runScripts(dummy); + suspendScripts = true; + try { + dummy.innerHTML = "<table>" + html + "</table>"; + } catch (e) { + suspendScripts = false; + throw e; + } + var table = x.parentNode; if (table) { @@ -843,12 +867,23 @@ for (var node = tbody.firstChild; node; node = next) { next = node.nextSibling; table.insertBefore(node, x); + suspendScripts = false; + runScripts(node); + suspendScripts = true; } } + + suspendScripts = false; } else if (pnode == "tr") { var dummy = document.createElement("body"); - dummy.innerHTML = "<table><tr>" + html + "</tr></table>"; - runScripts(dummy); + suspendScripts = true; + try { + dummy.innerHTML = "<table><tr>" + html + "</tr></table>"; + } catch (e) { + suspendScripts = false; + throw e; + } + var table = x.parentNode; if (table) { @@ -866,14 +901,27 @@ for (var node = tr.firstChild; node; node = next) { next = node.nextSibling; table.insertBefore(node, x); + suspendScripts = false; + runScripts(node); + suspendScripts = true; } - } + }; + + suspendScripts = false; } else { firstChild = document.createElement("span"); - firstChild.innerHTML = html; + + suspendScripts = true; + try { + firstChild.innerHTML = html; + if (x.parentNode) + x.parentNode.insertBefore(firstChild, x); + } catch (e) { + suspendScripts = false; + throw e; + } + suspendScripts = false; runScripts(firstChild); - if (x.parentNode) - x.parentNode.insertBefore(firstChild, x); } }; @@ -909,13 +957,18 @@ var cls = {v : null}; var html = flatten(cls, html); x.closures = cls.v; + suspendScripts = true; node.innerHTML = html; + suspendScripts = false; runScripts(node); } var maySuspend = true; function active(s) { + if (suspendScripts) + return; + var span = document.createElement("span"); addNode(span); var ms = maySuspend; @@ -944,6 +997,9 @@ } function inp(s, name) { + if (suspendScripts) + return; + var x = input(document.createElement("input"), s, function(x) { return function(v) { if (x.value != v) x.value = v; }; }, null, name); x.value = s.data; @@ -969,6 +1025,9 @@ } function sel(s, content) { + if (suspendScripts) + return; + var dummy = document.createElement("span"); dummy.innerHTML = "<select>" + content + "</select>"; var x = input(dummy.firstChild, s, function(x) { return function(v) { if (selectValue(x) != v) setSelectValue(x, v); }; }); @@ -989,6 +1048,9 @@ } function chk(s) { + if (suspendScripts) + return; + var x = input(document.createElement("input"), s, function(x) { return function(v) { if (x.checked != v) x.checked = v; }; }, "checkbox"); x.defaultChecked = x.checked = s.data; @@ -998,6 +1060,9 @@ } function tbx(s) { + if (suspendScripts) + return; + var x = input(document.createElement("textarea"), s, function(x) { return function(v) { if (x.value != v) x.value = v; }; }); x.innerHTML = s.data; @@ -1007,12 +1072,17 @@ } function dynClass(html, s_class, s_style) { + if (suspendScripts) + return; + var htmlCls = {v : null}; html = flatten(htmlCls, html); htmlCls = htmlCls.v; var dummy = document.createElement("body"); + suspendScripts = true; dummy.innerHTML = html; + suspendScripts = false; var html = dummy.firstChild; dummy.removeChild(html); addNode(html); @@ -1863,14 +1933,12 @@ } function giveFocus(id) { - window.setTimeout(function() { - var node = document.getElementById(id); + var node = document.getElementById(id); - if (node) - node.focus(); - else - er("Tried to give focus to ID not used in document: " + id); - }, 0); + if (node) + node.focus(); + else + er("Tried to give focus to ID not used in document: " + id); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/babySpawn.ur Fri Aug 03 12:39:04 2012 -0400 @@ -0,0 +1,3 @@ +fun main () : transaction page = return <xml><body> + <button onclick={fn _ => spawn (alert "Hi")}/> +</body></xml>
--- a/tests/dynTable.ur Fri Aug 03 08:38:47 2012 -0400 +++ b/tests/dynTable.ur Fri Aug 03 12:39:04 2012 -0400 @@ -8,14 +8,14 @@ <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>}/> + <button onclick={fn _ => 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>}/> + <button onclick={fn _ => set s1 <xml><td>Whoa!</td></xml>}/> </body></xml>