diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/js/urweb.js | 47 | ||||
-rw-r--r-- | lib/ur/basis.urs | 81 | ||||
-rw-r--r-- | lib/ur/top.urs | 4 |
3 files changed, 103 insertions, 29 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 2e350378..c3cab50a 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -1009,8 +1009,6 @@ function active(s) { if (suspendScripts) return; - var span = document.createElement("span"); - addNode(span); var ms = maySuspend; maySuspend = false; try { @@ -1020,7 +1018,11 @@ function active(s) { throw e; } maySuspend = ms; - setInnerHTML(span, html); + if (html != "") { + var span = document.createElement("span"); + addNode(span); + setInnerHTML(span, html); + } } function input(x, s, recreate, type, name) { @@ -1111,7 +1113,7 @@ function tbx(s) { return x; } -function dynClass(html, s_class, s_style) { +function dynClass(pnode, html, s_class, s_style) { if (suspendScripts) return; @@ -1119,7 +1121,7 @@ function dynClass(html, s_class, s_style) { html = flatten(htmlCls, html); htmlCls = htmlCls.v; - var dummy = document.createElement("body"); + var dummy = document.createElement(pnode); suspendScripts = true; dummy.innerHTML = html; suspendScripts = false; @@ -1150,23 +1152,23 @@ function dynClass(html, s_class, s_style) { if (s_style) { var htmlCls2 = s_class ? null : htmlCls; - var x = document.createElement("script"); - x.dead = false; - x.signal = s_style; - x.sources = null; - x.closures = htmlCls2; - - x.recreate = function(v) { - for (var ls = x.closures; ls != htmlCls2; ls = ls.next) + var y = document.createElement("script"); + y.dead = false; + y.signal = s_style; + y.sources = null; + y.closures = htmlCls2; + + y.recreate = function(v) { + for (var ls = y.closures; ls != htmlCls2; ls = ls.next) freeClosure(ls.data); var cls = {v : null}; html.style.cssText = flatten(cls, v); - x.closures = concat(cls.v, htmlCls2); + y.closures = concat(cls.v, htmlCls2); } - html.appendChild(x); - populate(x); + html.appendChild(y); + populate(y); } } @@ -1940,6 +1942,19 @@ function bless(s) { } +// Attribute name blessing + +function blessData(s) { + for (var i = 0; i < s.length; ++i) { + var c = s[i]; + if (!isAlnum(c) && c != '-' && c != '_') + er("Disallowed character in data-* attribute name"); + } + + return s; +} + + // CSS validation function atom(s) { diff --git a/lib/ur/basis.urs b/lib/ur/basis.urs index c94f2ba6..ce864563 100644 --- a/lib/ur/basis.urs +++ b/lib/ur/basis.urs @@ -796,11 +796,17 @@ val active : unit val script : unit -> tag [Code = transaction unit] head [] [] [] -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 [] [] [] +(* Type for HTML5 "data-*" attributes. *) +type data_attr +val data_attr : string (* Key *) -> string (* Value *) -> data_attr +(* This function will fail if the key doesn't meet HTML's lexical rules! *) +val data_attrs : data_attr -> data_attr -> data_attr -val body : unit -> tag [Onload = transaction unit, Onresize = transaction unit, Onunload = transaction unit, Onhashchange = transaction unit] +val head : unit -> tag [Data = data_attr] html head [] [] +val title : unit -> tag [Data = data_attr] head [] [] [] +val link : unit -> tag [Data = data_attr, Id = id, Rel = string, Typ = string, Href = url, Media = string] head [] [] [] + +val body : unit -> tag [Data = data_attr, Onload = transaction unit, Onresize = transaction unit, Onunload = transaction unit, Onhashchange = transaction unit] html body [] [] con bodyTag = fn (attrs :: {Type}) => ctx ::: {Unit} -> @@ -811,7 +817,7 @@ con bodyTagStandalone = fn (attrs :: {Type}) => -> [[Body] ~ ctx] => unit -> tag attrs ([Body] ++ ctx) [] [] [] -val br : bodyTagStandalone [Id = id] +val br : bodyTagStandalone [Data = data_attr, Id = id] con focusEvents = [Onblur = transaction unit, Onfocus = transaction unit] @@ -837,8 +843,8 @@ con scrollEvents = [Onscroll = transaction unit] con boxEvents = focusEvents ++ mouseEvents ++ keyEvents ++ resizeEvents ++ scrollEvents con tableEvents = focusEvents ++ mouseEvents ++ keyEvents -con boxAttrs = [Id = id, Title = string] ++ boxEvents -con tableAttrs = [Id = id, Title = string] ++ tableEvents +con boxAttrs = [Data = data_attr, Id = id, Title = string] ++ boxEvents +con tableAttrs = [Data = data_attr, Id = id, Title = string] ++ tableEvents val span : bodyTag boxAttrs val div : bodyTag boxAttrs @@ -865,6 +871,44 @@ val ul : bodyTag boxAttrs val hr : bodyTag boxAttrs +val pre : bodyTag boxAttrs + +(** sections **) +val section : bodyTag boxAttrs +val article : bodyTag boxAttrs +val nav : bodyTag boxAttrs +val aside : bodyTag boxAttrs +val footer : bodyTag boxAttrs +val header : bodyTag boxAttrs +val main : bodyTag boxAttrs + +(** forms **) +val meter : bodyTag boxAttrs +val progress : bodyTag boxAttrs +val output : bodyTag boxAttrs +val keygen : bodyTag boxAttrs +val datalist : bodyTag boxAttrs + +(** Interactive Elements **) +val details : bodyTag boxAttrs +val dialog : bodyTag boxAttrs +val menuitem : bodyTag boxAttrs + +(** Grouping Content **) +val figure : bodyTag boxAttrs +val figcaption : bodyTag boxAttrs + +(** Text Level Semantics **) +val data : bodyTag boxAttrs +val mark : bodyTag boxAttrs +val rp : bodyTag boxAttrs +val rt : bodyTag boxAttrs +val ruby : bodyTag boxAttrs +val summary : bodyTag boxAttrs +val time : bodyTag boxAttrs +val wbr : bodyTag boxAttrs +val bdi : bodyTag boxAttrs + val a : bodyTag ([Link = transaction page, Href = url, Target = string, Rel = string] ++ boxAttrs) val img : bodyTag ([Alt = string, Src = url, Width = int, Height = int, @@ -899,7 +943,7 @@ con formTag = fn (ty :: Type) (inner :: {Unit}) (attrs :: {Type}) => -> [[Form] ~ ctx] => nm :: Name -> unit -> tag attrs ([Form] ++ ctx) inner [] [nm = ty] -val hidden : formTag string [] [Id = string, Value = string] +val hidden : formTag string [] [Data = data_attr, Id = string, Value = string] val textbox : formTag string [] ([Value = string, Size = int, Placeholder = string, Source = source string, Onchange = transaction unit, Ontext = transaction unit] ++ boxAttrs) val password : formTag string [] ([Value = string, Size = int, Placeholder = string] ++ boxAttrs) @@ -933,12 +977,12 @@ val fieldValue : postField -> string val remainingFields : postField -> string con radio = [Body, Radio] -val radio : formTag (option string) radio [Id = id] +val radio : formTag (option string) radio [Data = data_attr, Id = id] val radioOption : unit -> tag ([Value = string, Checked = bool] ++ boxAttrs) radio [] [] [] con select = [Select] val select : formTag string select ([Onchange = transaction unit] ++ boxAttrs) -val option : unit -> tag [Value = string, Selected = bool] select [] [] [] +val option : unit -> tag [Data = data_attr, Value = string, Selected = bool] select [] [] [] val submit : ctx ::: {Unit} -> use ::: {Type} -> [[Form] ~ ctx] => @@ -990,19 +1034,30 @@ val td : other ::: {Unit} -> [other ~ [Body, Tr]] => unit -> tag ([Colspan = int, Rowspan = int] ++ tableAttrs) ([Tr] ++ other) ([Body] ++ other) [] [] +val thead : other ::: {Unit} -> [other ~ [Table]] => unit + -> tag tableAttrs + ([Table] ++ other) ([Table] ++ other) [] [] +val tbody : other ::: {Unit} -> [other ~ [Table]] => unit + -> tag tableAttrs + ([Table] ++ other) ([Table] ++ other) [] [] +val tfoot : other ::: {Unit} -> [other ~ [Table]] => unit + -> tag tableAttrs + ([Table] ++ other) ([Table] ++ other) [] [] + (** Definition lists *) val dl : other ::: {Unit} -> [other ~ [Body,Dl]] => unit - -> tag [] ([Body] ++ other) ([Dl] ++ other) [] [] + -> tag [Data = data_attr] ([Body] ++ other) ([Dl] ++ other) [] [] val dt : other ::: {Unit} -> [other ~ [Body,Dl]] => unit - -> tag [] ([Dl] ++ other) ([Body] ++ other) [] [] + -> tag [Data = data_attr] ([Dl] ++ other) ([Body] ++ other) [] [] val dd : other ::: {Unit} -> [other ~ [Body,Dl]] => unit - -> tag [] ([Dl] ++ other) ([Body] ++ other) [] [] + -> tag [Data = data_attr] ([Dl] ++ other) ([Body] ++ other) [] [] + (** Aborting *) diff --git a/lib/ur/top.urs b/lib/ur/top.urs index 30f1eaad..2ea86dc4 100644 --- a/lib/ur/top.urs +++ b/lib/ur/top.urs @@ -155,6 +155,10 @@ val mapX3 : K --> tf1 :: (K -> Type) -> tf2 :: (K -> Type) -> tf3 :: (K -> Type) -> r ::: {K} -> folder r -> $(map tf1 r) -> $(map tf2 r) -> $(map tf3 r) -> xml ctx [] [] +(* Note that the next two functions return elements in the _reverse_ of the natural order! + * Such a choice interacts well with the time complexity of standard list operations. + * It's easy to regain the natural order by inverting a query's 'ORDER BY' condition. *) + val queryL : tables ::: {{Type}} -> exps ::: {Type} -> [tables ~ exps] => sql_query [] [] tables exps |