Mercurial > urweb
changeset 1786:d794149b3713
<active>
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 21 Jul 2012 13:55:35 -0400 |
parents | ffd7ed3bc0b7 |
children | 69daa6d70299 |
files | doc/manual.tex lib/js/urweb.js lib/ur/basis.urs src/monoize.sml tests/active.ur |
diffstat | 5 files changed, 40 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/manual.tex Sat Jul 21 11:59:41 2012 -0400 +++ b/doc/manual.tex Sat Jul 21 13:55:35 2012 -0400 @@ -2136,7 +2136,11 @@ Currently, the only way to avoid undesired resets is to avoid regeneration of containing subtrees. There are two main strategies for achieving that goal. First, when changes to a subtree can be confined to CSS classes of tags, the \texttt{dynClass} pseudo-attribute may be used instead (see Section \ref{xml}), as it does not regenerate subtrees. Second, a single \cd{<dyn>} tag may be broken into multiple tags, in a way that makes finer-grained dependency structure explicit. This latter strategy can avoid ``spurious'' regenerations that are not actually required to achieve the intended semantics. -Transactions can be run on the client by including them in attributes like the $\mt{Onclick}$ attribute of $\mt{button}$, and GUI widgets like $\mt{ctextbox}$ have $\mt{Source}$ attributes that can be used to connect them to sources, so that their values can be read by code running because of, e.g., an $\mt{Onclick}$ event. +Transactions can be run on the client by including them in attributes like the $\mt{Onclick}$ attribute of $\mt{button}$, and GUI widgets like $\mt{ctextbox}$ have $\mt{Source}$ attributes that can be used to connect them to sources, so that their values can be read by code running because of, e.g., an $\mt{Onclick}$ event. It is also possible to create an ``active'' HTML fragment that runs a $\mt{transaction}$ to determine its content, possibly allocating some sources in the process: + +$$\begin{array}{l} + \mt{val} \; \mt{active} : \mt{unit} \to \mt{tag} \; [\mt{Code} = \mt{transaction} \; \mt{xbody}] \; \mt{body} \; [] \; [] \; [] +\end{array}$$ \subsubsection{Remote Procedure Calls}
--- a/lib/js/urweb.js Sat Jul 21 11:59:41 2012 -0400 +++ b/lib/js/urweb.js Sat Jul 21 13:55:35 2012 -0400 @@ -901,6 +901,12 @@ runScripts(node); } +function active(s) { + var span = document.createElement("span"); + addNode(span); + setInnerHTML(span, execF(s)); +} + function input(x, s, recreate, type, name) { if (name) x.name = name; if (type) x.type = type;
--- a/lib/ur/basis.urs Sat Jul 21 11:59:41 2012 -0400 +++ b/lib/ur/basis.urs Sat Jul 21 13:55:35 2012 -0400 @@ -767,6 +767,9 @@ val dyn : ctx ::: {Unit} -> use ::: {Type} -> bind ::: {Type} -> [ctx ~ [Dyn]] => unit -> tag [Signal = signal (xml ([Dyn] ++ ctx) use bind)] ([Dyn] ++ ctx) [] use bind +val active : unit + -> tag [Code = transaction xbody] body [] [] [] + val head : unit -> tag [] html head [] [] val title : unit -> tag [] head [] [] [] val link : unit -> tag [Id = id, Rel = string, Typ = string, Href = url, Media = string] head [] [] []
--- a/src/monoize.sml Sat Jul 21 11:59:41 2012 -0400 +++ b/src/monoize.sml Sat Jul 21 13:55:35 2012 -0400 @@ -3234,7 +3234,7 @@ val (style, fm) = monoExp (env, st, fm) style val (dynStyle, fm) = monoExp (env, st, fm) dynStyle - val dynamics = ["dyn", "ctextbox", "ccheckbox", "cselect", "coption", "ctextarea"] + val dynamics = ["dyn", "ctextbox", "ccheckbox", "cselect", "coption", "ctextarea", "active"] fun isSome (e, _) = case e of @@ -3541,9 +3541,19 @@ (L'.EStrcat ((L'.EJavaScript (L'.Script, e), loc), (L'.EPrim (Prim.String ("))</script>")), loc)), loc)), loc), fm) - | _ => raise Fail "Monoize: Bad dyn attributes" + | _ => raise Fail "Monoize: Bad <dyn> attributes" end + | "active" => + (case attrs of + [("Code", e, _)] => + ((L'.EStrcat + ((L'.EPrim (Prim.String ("<script type=\"text/javascript\">active(execD(")), loc), + (L'.EStrcat ((L'.EJavaScript (L'.Script, e), loc), + (L'.EPrim (Prim.String ("))</script>")), loc)), loc)), loc), + fm) + | _ => raise Fail "Monoize: Bad <active> attributes") + | "submit" => normal ("input type=\"submit\"", NONE) | "image" => normal ("input type=\"image\"", NONE) | "button" => normal ("input type=\"submit\"", NONE)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/active.ur Sat Jul 21 13:55:35 2012 -0400 @@ -0,0 +1,14 @@ +fun counter' () = + s <- source 0; + return <xml> + <dyn signal={n <- signal s; return (txt n)}/> + <button onclick={fn _ => n <- get s; set s (n + 1)}/> + </xml> + +fun counter () = <xml><active code={counter' ()}/></xml> + +fun main () : transaction page = return <xml><body> + {counter ()} + <hr/> + {counter ()} +</body></xml>