Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file eliom_content_core.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585# 1 "src/lib/eliom_content_core.client.ml"(* Ocsigen
* http://www.ocsigen.org
* Copyright (C) 2012 Vincent Balat, Benedikt Becker
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)(* This the core of [Eliom_content] without its dependencies to [Eliom_service],
[Eliom_client] et al.
Its name is not [Eliom_content_base] because this would
suggest the sharing between server and client. *)openJs_of_ocamlopenEliom_libmoduleXml=structincludeEliom_runtime.RawXMLmoduleW=Xml_wrap.NoWraptype'awrap='atype'alist_wrap='alisttypeecontent=|Empty|Commentofstring|EncodedPCDATAofstring|PCDATAofstring|Entityofstring|Leafofename*attriblist|Nodeofename*attriblist*eltlistandnode=|DomNodeofDom.nodeJs.t|TyXMLNodeofecontent|ReactNodeofeltReact.signal|ReactChildrenofecontent*eltReactiveData.RList.tandelt={(* See Eliom_content.Html.To_dom for the 'unwrap' function that convert
the server's tree representation into the client one. *)mutableelt:nodelazy_t;node_id:node_id}letcontente=matchLazy.forcee.eltwith|ReactChildren_|ReactNode_|DomNode_->assertfalse(* TODO *)|TyXMLNodeelt->eltletget_nodee=Lazy.forcee.eltletset_dom_nodeeltnode=elt.elt<-Lazy.from_val(DomNodenode)letget_node_idelt=elt.node_idletmake?(id=NoId)elt ={elt=Lazy.from_val(TyXMLNodeelt);node_id=id}letmake_dom?(id=NoId)node={elt=Lazy.from_val(DomNodenode);node_id=id}letmake_lazy?(id=NoId)lazy_elt=letf()=letelt=Lazy.forcelazy_eltinassert(elt.node_id=id);Lazy.forceelt.eltin{node_id=id;elt=Lazy.from_funf}letforce_lazy{elt;_}=ignore(Lazy.forceelt)letmake_react ?(id=NoId)signal={elt=Lazy.from_val(ReactNodesignal);node_id=id}letempty()=makeEmptyletcommentc=make(Commentc)letpcdatad=make(PCDATAd)letencodedpcdatad=make(EncodedPCDATAd)letentitye=make(Entitye)letleaf?(a=[])name=make(Leaf(name,a))letnode?(a=[])namechildren=make(Node(name,a,children))letlazy_node?anamechildren=node?aname(Eliom_lazy.forcechildren)typeevent_handler=Dom_html.eventJs.t->unittypemouse_event_handler=Dom_html.mouseEventJs.t->unittypekeyboard_event_handler=Dom_html.keyboardEventJs.t->unittypetouch_event_handler=Dom_html.touchEventJs.t->unitletevent_handler_attribname(value:event_handler)=internal_event_handler_attribname(Caml(CE_client_closurevalue))letmouse_event_handler_attribname(value:mouse_event_handler)=internal_event_handler_attribname(Caml(CE_client_closure_mouse value))letkeyboard_event_handler_attribname(value:keyboard_event_handler)=internal_event_handler_attribname(Caml(CE_client_closure_keyboardvalue))lettouch_event_handler_attribname(value:touch_event_handler)=internal_event_handler_attribname(Caml(CE_client_closure_touchvalue))letnode_react_children?(a=[])namechildren={elt=Lazy.from_val(ReactChildren(Node(name,a,[]),children));node_id=NoId}letend_re=Regexp.regexp_string"]]>"letmake_node_name=letnode_id_counter=ref0infun?(global=true)()->incrnode_id_counter;(ifglobalthen"global_"else"")^"client_"^string_of_int!node_id_counterletmake_process_node?(id=make_node_name~global:true())elt={eltwithnode_id=ProcessIdid}letmake_request_node?(reset=true)elt=letf()=letid=RequestId(make_node_name~global:false())in{eltwithnode_id=id}inifresetthenf()elsematchelt.node_idwithEliom_runtime.RawXML.NoId->f()|_->eltletcdatas=lets'="\n<![CDATA[\n"^Regexp.global_replaceend_res""^"\n]]>\n"inencodedpcdatas'letcdata_scripts=lets'="\n//<![CDATA[\n"^Regexp.global_replaceend_res""^"\n//]]>\n"inencodedpcdatas'letcdata_styles=lets'="\n/* <![CDATA[ */\n"^Regexp.global_replaceend_res""^"\n/* ]]> */\n"inencodedpcdatas'letset_classesnode_id=function|(Empty|Comment_|EncodedPCDATA_|PCDATA_|Entity_)ase->e|Leaf(ename,attribs)->Leaf(ename,filter_class_attribsnode_idattribs)|Node(ename,attribs,sons)->Node(ename,filter_class_attribsnode_idattribs,sons)letset_classes_of_eltelt=matchLazy.forceelt.eltwith|DomNode_->failwith"Eliom_content_core.set_classes_of_elt"|ReactNode_->failwith"Eliom_content_core.set_classes_of_elt"|ReactChildren_->failwith"Eliom_content_core.set_classes_of_elt"|TyXMLNodeecontent->{eltwithelt=Lazy.from_val(TyXMLNode(set_classeselt.node_idecontent))}letstring_of_node_id=function|NoId->"NoId"|ProcessIds->"ProcessId "^s|RequestIds->"RequestId "^sendmoduleXml_wed=structmoduleW=Js_of_ocaml_tyxml.Tyxml_js.Wraptype'awrap='aW.ttype'alist_wrap='aW.tlisttypeuri=Xml.uriletstring_of_uri=Xml.string_of_urileturi_of_string=Xml.uri_of_stringtypeaname=Xml.anametypeevent_handler=Xml.event_handlertypemouse_event_handler=Xml.mouse_event_handlertypekeyboard_event_handler=Xml.keyboard_event_handlertypetouch_event_handler=Xml.touch_event_handlertypeattrib=Xml.attribletfloat_attribnames:attrib=(name,Xml.RAReact(Js_of_ocaml_tyxml.Tyxml_js.Wrap.fmap(funf->Some(Xml.AFloatf))s))letint_attribnames=name,Xml.RAReact(React.S.map(funf->Some(Xml.AIntf))s)letstring_attribnames=name,Xml.RAReact(React.S.map(funf->Some(Xml.AStrf))s)letspace_sep_attribnames=name,Xml.RAReact(React.S.map(funf->Some(Xml.AStrL(Xml.Space,f)))s)letcomma_sep_attribnames=name,Xml.RAReact(React.S.map(funf->Some(Xml.AStrL(Xml.Comma,f)))s)letevent_handler_attrib=Xml.event_handler_attribletmouse_event_handler_attrib=Xml.mouse_event_handler_attribletkeyboard_event_handler_attrib=Xml.keyboard_event_handler_attriblettouch_event_handler_attrib=Xml.touch_event_handler_attribleturi_attribnamevalue=(name,Xml.RAReact(React.S.map(funf->Some(Xml.AStr(Eliom_lazy.forcef)))value))leturis_attribnamevalue=(name,Xml.RAReact(React.S.map(funf->Some(Xml.AStrL(Xml.Space,Eliom_lazy.forcef)))value))typeelt=Xml.elttypeename=Xml.enameletempty=Xml.emptyletcomment=Xml.commentletpcdatas=Xml.make_react(React.S.mapXml.pcdatas)letencodedpcdatas=Xml.make_react(React.S.mapXml.encodedpcdatas)letentity=Xml.entityletleaf=Xml.leafletnode?anamel=Xml.node_react_children?anamelletcdata=Xml.cdataletcdata_script=Xml.cdata_scriptletcdata_style=Xml.cdata_styleendmoduleSvg=structmoduleEv'(A:sigtype'aattribmoduleUnsafe:sigvalstring_attrib:string->string->'aattribendend)=structleta_onaborts=A.Unsafe.string_attrib"onabort"sleta_onactivates=A.Unsafe.string_attrib"onactivate"sleta_onbegins=A.Unsafe.string_attrib"onbegin"sleta_onends=A.Unsafe.string_attrib"onend"sleta_onerrors=A.Unsafe.string_attrib"onerror"sleta_onfocusins=A.Unsafe.string_attrib"onfocusin"sleta_onfocusouts=A.Unsafe.string_attrib"onfocusout"sleta_onloads=A.Unsafe.string_attrib"onload"sleta_onrepeats=A.Unsafe.string_attrib"onrepeat"sleta_onresizes=A.Unsafe.string_attrib"onresize"sleta_onscrolls=A.Unsafe.string_attrib"onscroll"sleta_onunloads=A.Unsafe.string_attrib"onunload"sleta_onzooms=A.Unsafe.string_attrib"onzoom"sleta_onclicks=A.Unsafe.string_attrib"onclick"sleta_onmousedowns=A.Unsafe.string_attrib"onmousedown"sleta_onmouseups=A.Unsafe.string_attrib"onmouseup"sleta_onmouseovers=A.Unsafe.string_attrib"onmouseover"sleta_onmouseouts=A.Unsafe.string_attrib"onmouseout"sleta_onmousemoves=A.Unsafe.string_attrib"onmousemove"sleta_ontouchstarts=A.Unsafe.string_attrib"ontouchstart"sleta_ontouchends=A.Unsafe.string_attrib"ontouchend"sleta_ontouchmoves=A.Unsafe.string_attrib"ontouchmove"sleta_ontouchcancels=A.Unsafe.string_attrib"ontouchcancel"sendmoduleD=structmoduleRaw'=Svg_f.Make(structincludeXmlletmakeelt=make_request_node(makeelt)letempty()=makeEmptyletcommentc=make(Commentc)letpcdatad=make(PCDATAd)letencodedpcdatad=make(EncodedPCDATAd)letentitye=make(Entitye)letleaf?(a=[])name=make(Leaf(name,a))letnode?(a=[])namechildren=make(Node(name,a,children))end)moduleRaw=structincludeRaw'includeEv'(Raw')endincludeRaw'endmoduleF=structmoduleRaw'=Svg_f.Make(Xml)moduleRaw=structincludeRaw'includeEv'(Raw')endincludeRaw'endmoduleR=structletnodes=Xml.make_reactsmoduleRaw=Svg_f.Make(Xml_wed)includeRawendtype+'aelt='aF.elttype'awrap='aF.wraptype'alist_wrap='aF.list_wraptype+'aattrib='aF.attribtypeuri=F.urimoduleId=structtype'aid=string(* FIXME invariant type parameter ? *)letnew_elt_id:?global:bool->unit->'aid=Xml.make_node_nameletcreate_named_elt~(id:'aid)elt=D.tot(Xml.make_process_node~id(D.toeltelt))letcreate_global_eltelt=D.tot(Xml.make_process_node(D.toeltelt))letcreate_request_elt?(reset=true)elt=D.tot(Xml.make_request_node~reset(D.toeltelt))letstring_of_idx=xendmoduleOf_dom=structletrebuild_xml(node:'aJs.t):'aF.elt=Xml.make_dom(node:>Dom.nodeJs.t)letof_element:Dom_html.elementJs.t->'aelt=rebuild_xmlendendmoduleHtml=structmoduleEv'(A:sigtype'aattribmoduleUnsafe:sigvalstring_attrib:string->string->'aattribendend)=structleta_onaborts=A.Unsafe.string_attrib"onabort"sleta_onafterprints=A.Unsafe.string_attrib"onafterprint"sleta_onbeforeprints=A.Unsafe.string_attrib"onbeforeprint"sleta_onbeforeunloads=A.Unsafe.string_attrib"onbeforeunload"sleta_onblurs=A.Unsafe.string_attrib"onblur"sleta_oncanplays=A.Unsafe.string_attrib"oncanplay"sleta_oncanplaythroughs=A.Unsafe.string_attrib"oncanplaythrough"sleta_onchanges=A.Unsafe.string_attrib"onchange"sleta_oncloses=A.Unsafe.string_attrib"onclose"sleta_ondurationchanges=A.Unsafe.string_attrib"ondurationchange"sleta_onemptieds=A.Unsafe.string_attrib"onemptied"sleta_onendeds=A.Unsafe.string_attrib"onended"sleta_onerrors=A.Unsafe.string_attrib"onerror"sleta_onfocuss=A.Unsafe.string_attrib"onfocus"sleta_onformchanges=A.Unsafe.string_attrib"onformchange"sleta_onforminputs=A.Unsafe.string_attrib"onforminput"sleta_onhashchanges=A.Unsafe.string_attrib"onhashchange"sleta_oninputs=A.Unsafe.string_attrib"oninput"sleta_oninvalids=A.Unsafe.string_attrib"oninvalid"sleta_onmousewheels=A.Unsafe.string_attrib"onmousewheel"sleta_onofflines=A.Unsafe.string_attrib"onoffline"sleta_ononlines=A.Unsafe.string_attrib"ononline"sleta_onpauses=A.Unsafe.string_attrib"onpause"sleta_onplays=A.Unsafe.string_attrib"onplay"sleta_onplayings=A.Unsafe.string_attrib"onplaying"sleta_onpagehides=A.Unsafe.string_attrib"onpagehide"sleta_onpageshows=A.Unsafe.string_attrib"onpageshow"sleta_onpopstates=A.Unsafe.string_attrib"onpopstate"sleta_onprogresss=A.Unsafe.string_attrib"onprogress"sleta_onratechanges=A.Unsafe.string_attrib"onratechange"sleta_onreadystatechanges=A.Unsafe.string_attrib"onreadystatechange"sleta_onredos=A.Unsafe.string_attrib"onredo"sleta_onresizes=A.Unsafe.string_attrib"onresize"sleta_onscrolls=A.Unsafe.string_attrib"onscroll"sleta_onseekeds=A.Unsafe.string_attrib"onseeked"sleta_onseekings=A.Unsafe.string_attrib"onseeking"sleta_onselects=A.Unsafe.string_attrib"onselect"sleta_onshows=A.Unsafe.string_attrib"onshow"sleta_onstalleds=A.Unsafe.string_attrib"onstalled"sleta_onstorages=A.Unsafe.string_attrib"onstorage"sleta_onsubmits=A.Unsafe.string_attrib"onsubmit"sleta_onsuspends=A.Unsafe.string_attrib"onsuspend"sleta_ontimeupdates=A.Unsafe.string_attrib"ontimeupdate"sleta_onundos=A.Unsafe.string_attrib"onundo"sleta_onunloads=A.Unsafe.string_attrib"onunload"sleta_onvolumechanges=A.Unsafe.string_attrib"onvolumechange"sleta_onwaitings=A.Unsafe.string_attrib"onwaiting"sleta_onloads=A.Unsafe.string_attrib"onload"sleta_onloadeddatas=A.Unsafe.string_attrib"onloadeddata"sleta_onloadedmetadatas=A.Unsafe.string_attrib"onloadedmetadata"sleta_onloadstarts=A.Unsafe.string_attrib"onloadstart"sleta_onmessages=A.Unsafe.string_attrib"onmessage"sleta_onclicks=A.Unsafe.string_attrib"onclick"sleta_oncontextmenus=A.Unsafe.string_attrib"oncontextmenu"sleta_ondblclicks=A.Unsafe.string_attrib"ondblclick"sleta_ondrags=A.Unsafe.string_attrib"ondrag"sleta_ondragends=A.Unsafe.string_attrib"ondragend"sleta_ondragenters=A.Unsafe.string_attrib"ondragenter"sleta_ondragleaves=A.Unsafe.string_attrib"ondragleave"sleta_ondragovers=A.Unsafe.string_attrib"ondragover"sleta_ondragstarts=A.Unsafe.string_attrib"ondragstart"sleta_ondrops=A.Unsafe.string_attrib"ondrop"sleta_onmousedowns=A.Unsafe.string_attrib"onmousedown"sleta_onmouseups=A.Unsafe.string_attrib"onmouseup"sleta_onmouseovers=A.Unsafe.string_attrib"onmouseover"sleta_onmousemoves=A.Unsafe.string_attrib"onmousemove"sleta_onmouseouts=A.Unsafe.string_attrib"onmouseout"sleta_ontouchstarts=A.Unsafe.string_attrib"ontouchstart"sleta_ontouchends=A.Unsafe.string_attrib"ontouchend"sleta_ontouchmoves=A.Unsafe.string_attrib"ontouchmove"sleta_ontouchcancels=A.Unsafe.string_attrib"ontouchcancel"sleta_onkeypresss=A.Unsafe.string_attrib"onkeypress"sleta_onkeydowns=A.Unsafe.string_attrib"onkeydown"sleta_onkeyups=A.Unsafe.string_attrib"onkeyup"sendmoduleD=structmoduleXml'=structincludeXmlletmakeelt=make_request_node(makeelt)letempty()=makeEmptyletcommentc=make(Commentc)letpcdatad=make(PCDATAd)letencodedpcdatad=make(EncodedPCDATAd)letentitye=make(Entitye)letleaf?(a=[])name=make(Leaf(name,a))letnode?(a=[])namechildren=make(Node(name,a,children))letlazy_node?(a=[])namechildren=make(Node(name,a,Eliom_lazy.forcechildren))endmoduleRaw'=Html_f.Make(Xml')(Svg.D.Raw')moduleRaw=structincludeRaw'includeEv'(Raw')endincludeRaw'type('a,'b,'c)lazy_star=?a:'aattriblist->'beltlistEliom_lazy.request->'celtletlazy_form?(a=[])elts=tot(Xml'.lazy_node~a:(to_xmlattribsa)"form"(Eliom_lazy.from_fun(fun()->toeltl(Eliom_lazy.forceelts))))endmoduleR=structletnodes=Xml.make_reactsmoduleRaw=Html_f.Make(Xml_wed)(Svg.R)letfilter_attrib(name,a)on=letv=matchawith|Xml.RAa->Xml.RAReact(React.S.map(functiontrue->Somea|false->None)on)|Xml.RAReacts->Xml.RAReact(React.S.l2(funvb->ifbthenvelseNone)son)|Xml.RALazyStrs->Xml.RAReact(React.S.map(function|true->Some(Xml.AStr(Eliom_lazy.forces))|false->None)on)|Xml.RALazyStrL(sep,l)->Xml.RAReact(React.S.map(function|true->Some(Xml.AStrL(sep,List.mapEliom_lazy.forcel))|false->None)on)|Xml.RACamlEventHandler_->failwith"R.filter_attrib not implemented for event handler"|Xml.RAClient_->assertfalseinname,vincludeRawendmoduleF=structmoduleXml'=XmlmoduleRaw'=Html_f.Make(Xml')(Svg.F.Raw')moduleRaw=structincludeRaw'includeEv'(Raw')endincludeRaw'type('a,'b,'c)lazy_star=?a:'aattriblist->'beltlistEliom_lazy.request->'celtletlazy_form?(a=[])elts=tot(Xml'.lazy_node~a:(to_xmlattribsa)"form"(Eliom_lazy.from_fun(fun()->toeltl(Eliom_lazy.forceelts))))endtype+'aelt='aF.elttype'awrap='aF.wraptype'alist_wrap='aF.list_wraptype+'aattrib='aF.attribtypeuri=F.urimoduleId=structtype'aid=string(* FIXME invariant type parameter ? *)letnew_elt_id:?global:bool->unit->'aid=Xml.make_node_nameletcreate_named_elt~(id:'aid)elt=D.tot(Xml.make_process_node~id(D.toeltelt))letcreate_global_eltelt=D.tot(Xml.make_process_node(D.toeltelt))letcreate_request_elt?(reset=true)elt=D.tot(Xml.make_request_node~reset(D.toeltelt))letstring_of_idx=xendmoduleCustom_data=structtype'at={name:string;to_string:'a->string;of_string:string->'a;default:'aoption}letcreate~name?default~to_string~of_string()={name;of_string;to_string;default}letcreate_json~name?defaulttyp={name;of_string=of_json~typ;to_string=to_json~typ;default}letattribcustom_datavalue=F.a_user_datacustom_data.name(custom_data.to_stringvalue)letattribute_namename="data-"^nameletget_dom(element:Dom_html.elementJs.t)custom_data=Js.Opt.caseelement##(getAttribute(Js.string(attribute_namecustom_data.name)))(fun()->matchcustom_data.defaultwith|Somevalue->value|None->raiseNot_found)(funstr->custom_data.of_string(Js.to_stringstr))letset_domelementcustom_datavalue=element##(setAttribute(Js.string(attribute_namecustom_data.name))(Js.string(custom_data.to_stringvalue)))endmoduleOf_dom=Js_of_ocaml_tyxml.Tyxml_cast.MakeOf(structtype'aelt='aF.eltletelt(node:'aJs.t):'aelt=Xml.make_dom(node:>Dom.nodeJs.t)end)letset_classes_of_eltelt=F.tot(Xml.set_classes_of_elt(F.toeltelt))end