changeset 1792:3d823d8424cc

Disallow suspending operations in <active code={...}>
author Adam Chlipala <adam@chlipala.net>
date Mon, 23 Jul 2012 09:03:41 -0400
parents 2f8b8952fe27
children 446e73902b09
files lib/js/urweb.js tests/setActive.ur
diffstat 2 files changed, 31 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/lib/js/urweb.js	Mon Jul 23 08:38:39 2012 -0400
+++ b/lib/js/urweb.js	Mon Jul 23 09:03:41 2012 -0400
@@ -913,10 +913,21 @@
     runScripts(node);
 }
 
+var maySuspend = true;
+
 function active(s) {
     var span = document.createElement("span");
     addNode(span);
-    setInnerHTML(span, execF(s));
+    var ms = maySuspend;
+    maySuspend = false;
+    try {
+        var html = execF(s);
+    } catch (e) {
+        maySuspend = ms;
+        throw e;
+    }
+    maySuspend = ms;
+    setInnerHTML(span, html);
 }
 
 function input(x, s, recreate, type, name) {
@@ -1002,10 +1013,10 @@
 
     var dummy = document.createElement("body");
     dummy.innerHTML = html;
-    runScripts(dummy);
     var html = dummy.firstChild;
     dummy.removeChild(html);
     addNode(html);
+    runScripts(html);
 
     if (s_class) {
         var x = document.createElement("script");
@@ -1285,6 +1296,9 @@
 }
 
 function rc(prefix, uri, parse, k, needsSig) {
+    if (!maySuspend)
+        er("May not 'rpc' in 'code' for <active>");
+
     uri = cat(prefix, uri);
     uri = flattenLocal(uri);
     var xhr = getXHR();
@@ -1463,6 +1477,9 @@
 }
 
 function rv(chn, parse, k) {
+    if (!maySuspend)
+        er("May not 'recv' in 'code' for <active>");
+
     if (chn == null)
         return;
 
@@ -1490,6 +1507,9 @@
 }
 
 function sl(ms, k) {
+    if (!maySuspend)
+        er("May not 'sleep' in 'code' for <active>");
+
     window.setTimeout(function() { k(null); }, ms);
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/setActive.ur	Mon Jul 23 09:03:41 2012 -0400
@@ -0,0 +1,9 @@
+fun main () : transaction page =
+    i <- fresh;
+    x <- source <xml/>;
+    return <xml>
+      <body>
+        <dyn signal={signal x} />
+        <active code={set x <xml><ctextbox/><ctextbox id={i}/><ctextbox/><active code={giveFocus i; return <xml/>}/></xml>; return <xml/>}/>
+      </body>
+    </xml>