Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file eliom_content_core.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444# 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_nodeelt node=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_mousevalue))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=structmoduleD=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)includeRawendmoduleF=structmoduleRaw=Svg_f.Make(Xml)includeRawendmoduleR=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=structmoduleD=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)includeRawtype('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)includeRawtype('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