Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file eliom_content_core.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558# 1 "src/lib/eliom_content_core.server.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.
*)openJs_of_ocamlopenEliom_lib(* This the core of [Eliom_content] without its dependencies to [Eliom_service] et al.
Its name is not [Eliom_content_base] because this would suggest the sharing
between server and client. *)(*****************************************************************************)moduleXml=structincludeEliom_runtime.RawXMLmoduleW=Xml_wrap.NoWraptype'awrap='atype'alist_wrap='alisttypeecontent=|Empty|Commentofstring|EncodedPCDATAofstring|PCDATAofstring|Entityofstring|Leafofename*attriblist|Nodeofename*attriblist*eltlistandrecontent=RELazyofecontentEliom_lazy.request|REofecontentandelt'={recontent:recontent;node_id:node_id;unwrapper_mark:Eliom_wrap.unwrapper}[@@warning"-69"]andelt={elt:elt';wrapper_mark:eltEliom_wrap.wrapper}[@@warning"-69"](** Values of type [elt] are wrapped values of type [elt']. *)letcontent{elt;_}=matchelt.recontentwithREe->e|RELazye->Eliom_lazy.force emoduleNode_id_set=Set.Make(structtypet=node_idletcompare:t->t->int=compareend)letnode_ids_in_content=refNode_id_set.emptyletwrapper_mark =Eliom_wrap.create_wrapper(fun{elt;_}->ifNode_id_set.memelt.node_id!node_ids_in_contentthen{eltwithrecontent=REEmpty}elseelt)letwrappagevalue=letnode_ids=ref[]inletreccollect_node_ids({elt;_}aselt')=let{node_id;_}=eltinifnode_id<>NoIdthennode_ids:=node_id::!node_ids;matchcontentelt'with|Empty|Comment_|EncodedPCDATA_|PCDATA_|Entity_|Leaf_->()|Node(_,_,children)->List.itercollect_node_idschildrenincollect_node_idspage;node_ids_in_content:=List.fold_rightNode_id_set.add!node_idsNode_id_set.empty;letres=Eliom_wrap.wrapvalueinnode_ids_in_content:=Node_id_set.empty;resletget_node_id{elt;_}=elt.node_idlettyxml_unwrap_id=Eliom_wrap.id_of_intEliom_runtime.tyxml_unwrap_id_intletmakeelt={elt={recontent=REelt;node_id=NoId;unwrapper_mark=Eliom_wrap.create_unwrappertyxml_unwrap_id};wrapper_mark}letmake_lazyelt={elt={recontent=RELazyelt;node_id=NoId;unwrapper_mark=Eliom_wrap.create_unwrappertyxml_unwrap_id};wrapper_mark}letempty()=makeEmptyletcommentc=make(Commentc)letpcdatad=make(PCDATAd)letencodedpcdatad=make(EncodedPCDATA d)letentitye=make(Entitye)letleaf?(a=[])name=make(Leaf(name,a))letnode?(a=[])namechildren=make (Node(name,a,children))letlazy_node?(a=[])namechildren=make_lazy(Eliom_lazy.from_fun(fun()->Node(name,a,Eliom_lazy.forcechildren)))type event_handler=(Dom_html.eventJs.t->unit)Eliom_client_value.ttypemouse_event_handler=(Dom_html.mouseEventJs.t->unit)Eliom_client_value.ttypekeyboard_event_handler=(Dom_html.keyboardEventJs.t->unit)Eliom_client_value.ttypetouch_event_handler=(Dom_html.touchEventJs.t->unit)Eliom_client_value.tletmake_cryptographic_safe_string()=(* FIX: we should directly produce a string of the right length *)String.sub(make_cryptographic_safe_string())012letcaml_event_handlercf=letcrypto=make_cryptographic_safe_string()inCE_registered_closure(crypto,Eliom_lib.to_polycf)letevent_handlercf=Caml(caml_event_handlercf)letbiggest_event_handler_attribnamecf=internal_event_handler_attribname(event_handlercf)letevent_handler_attribname(cf:event_handler)=biggest_event_handler_attribnamecfletmouse_event_handler_attribname(cf:mouse_event_handler)=biggest_event_handler_attribnamecfletkeyboard_event_handler_attribname(cf:keyboard_event_handler)=biggest_event_handler_attrib namecflettouch_event_handler_attribname(cf:touch_event_handler)=biggest_event_handler_attribnamecfletclient_attrib?init(x:attribEliom_client_value.t)=letcrypto=make_cryptographic_safe_string()inletempty_name=""inempty_name,RAClient(crypto,init,Eliom_lib.to_polyx)letclosing_cdata=Re.Pcre.(regexp(quote"]]>"))letcdatas=(* GK *)(* For security reasons, we do not allow "]]>" inside CDATA
(as this string is to be considered as the end of the cdata)
*)lets'="\n<![CDATA[\n"^Re.replace_stringclosing_cdata~by:""s^"\n]]>\n"inencodedpcdatas'letcdata_scripts=(* GK *)(* For security reasons, we do not allow "]]>" inside CDATA
(as this string is to be considered as the end of the cdata)
*)lets'="\n//<![CDATA[\n"^Re.replace_stringclosing_cdata~by:""s^"\n//]]>\n"inencodedpcdatas'letcdata_styles=(* GK *)(* For security reasons, we do not allow "]]>" inside CDATA
(as this string is to be considered as the end of the cdata)
*)lets'="\n/* <![CDATA[ */\n"^Re.replace_stringclosing_cdata~by:""s^"\n/* ]]> */\n"inencodedpcdatas'letmake_node_name~global()=(* !!! The "global_" prefix is checked in eliom_client.client.ml !!! *)(ifglobalthen"global_"else"")(* FIX: put a prefix as a debugging option? *)^(* "server_" ^ *)make_cryptographic_safe_string()letmake_process_node?(id=make_node_name~global:true())elt'={elt'withelt={elt'.eltwithnode_id=ProcessIdid}}letmake_request_node?(reset=false)elt'=letf()=letid=RequestId(make_node_name~global:false())in{elt'withelt={elt'.eltwithnode_id=id}}inifresetthenf()elsematchelt'.elt.node_idwith|Eliom_runtime.RawXML.NoId->f()|_->elt'(** Ref tree *)letrecfold_attribfaccelt=matchcontenteltwith|Empty|EncodedPCDATA_|PCDATA_|Entity_|Comment_->acc|Leaf(_,attribs)->faccattribs|Node(_,attribs,elts)->letacc=faccattribsinList.fold_left(fold_attribf)acceltsletmake_event_handler_tableelt=letfaccattribs=List.fold_right(funattacc->matchracontentattwith|RACamlEventHandler(CE_registered_closure(closure_id,cv))->ClosureMap.addclosure_idcvacc|_->acc)attribsaccinfold_attribfClosureMap.emptyeltletmake_client_attrib_tableelt:client_attrib_table=letfaccattribs=List.fold_right(funattacc->matchracontentattwith|RAClient(id,_,cv)->ClosureMap.addidcvacc|_->acc)attribsaccinfold_attribfClosureMap.emptyeltletset_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)letcontent{elt;_}=letc=matchelt.recontentwithREe->e|RELazye->Eliom_lazy.forceeinset_classeselt.node_idcendmoduleSvg=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=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))endmoduleRaw'=Svg_f.Make(Xml')moduleRaw=structincludeRaw'includeEv'(Raw')endletclient_attrib?init(x:'aRaw.attribEliom_client_value.t)=Xml.client_attrib?initxincludeRaw'endmoduleF=structmoduleRaw'=Svg_f.Make(Xml)moduleRaw=structincludeRaw'includeEv'(Raw')endincludeRaw'endmoduleMake(Xml:Xml_sigs.Twithtypeelt=Xml.eltandtypeattrib=Xml.attrib)(C:Svg_sigs.Wrapped_functionswithmoduleXml=Xml)=Svg_f.Make_with_wrapped_functions(Xml)(C)type+'aelt='aF.elttype'awrap='atype'alist_wrap='alisttype+'aattrib='aF.attribtypeuri=F.urimoduleId=structtype'aid=string(* FIXME invariant type parameter ? *)letnew_elt_id:?global:bool->unit->'aid=fun?(global=true)()->Xml.make_node_name~global()letcreate_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?resetelt=D.tot(Xml.make_request_node?reset(D.toeltelt))endmodulePrinter=Xml_print.Make_typed_fmt(Xml)(F)endmoduleHtml=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=struct(* This is [Eliom_content.Xml] adapted such that request nodes are produced *)moduleXml'=structincludeXmlletmakeelt=make_request_node(makeelt)letmake_lazyelt=make_request_node(make_lazyelt)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_lazy(Eliom_lazy.from_fun(fun()->Node(name,a,Eliom_lazy.forcechildren)))endmoduleRaw'=Html_f.Make(Xml')(Svg.F.Raw')moduleRaw=structincludeRaw'includeEv'(Raw')endletclient_attrib?init(x:'aRaw.attribEliom_client_value.t)=Xml.client_attrib?initxincludeRaw'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))))endmoduleF=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))))endmoduleMake(Xml:Xml_sigs.Twithtypeelt=Xml.eltandtypeattrib=Xml.attrib)(C:Html_sigs.Wrapped_functionswithmoduleXml=Xml)(Svg:Svg_sigs.TwithmoduleXml:=Xml)=Html_f.Make_with_wrapped_functions(Xml)(C)(Svg)type+'aelt='aF.elttype'awrap='atype'alist_wrap='alisttype+'aattrib='aF.attribtypeuri=F.urimoduleId=structtype'aid=string(* FIXME invariant type parameter ? *)letnew_elt_id:?global:bool->unit->'aid=fun?(global=true)()->Xml.make_node_name~global()letcreate_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?resetelt=D.tot(Xml.make_request_node?reset(D.toeltelt))lethave_idnameelt=Xml.get_node_id(D.toeltelt)=Xml.ProcessIdnameendmoduleCustom_data=structtype'at={name:string;to_string:'a->string;of_string:string->'a;default:'aoption}[@@warning"-69"]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)endmodulePrinter=Xml_print.Make_typed_fmt(Xml)(F)end