123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200(* This file is part of the ocaml-vdom package, released under the terms of an MIT-like license. *)(* See the attached LICENSE file. *)(* Copyright 2016 by LexiFi. *)moduleCmd=structtype'msgt=..type'msgt+=|Echoof'msg|Batchof'msgtlist|Map:('a->'msg)*'at->'msgtletechomsg=Echomsgletbatchl=Batchlletmapfx=Map(f,x)endmoduleCustom=structtypet=..typeevent=..endtypemouse_event={x:int;y:int;page_x:float;page_y:float;buttons:int;alt_key:bool;ctrl_key:bool;shift_key:bool}typekey_event={which:int;alt_key:bool;ctrl_key:bool;shift_key:bool}type'msgevent_handler=|MouseDownof(mouse_event->'msg)|Clickof(mouse_event->'msg)|DblClickof(mouse_event->'msg)|Focusof'msg|Blurof'msg|Inputof(string->'msg)|Changeof(string->'msg)|ChangeIndexof(int->'msg)|ChangeCheckedof(bool->'msg)|MouseMoveof(mouse_event->'msg)|KeyDownof(key_event->'msg)|KeyDownCancelof(key_event->'msgoption)|ContextMenuof(mouse_event->'msg)|CustomEventof(Custom.event->'msgoption)typeprop_val=|Stringofstring|Intofint|Floatoffloat|Boolofbooltype'msgattribute=|Propertyofstring*prop_val|Styleofstring*string|Handlerof'msgevent_handler|Attributeofstring*stringletonmousedownmsg=Handler(MouseDownmsg)letonclickmsg=Handler(Clickmsg)letondblclickmsg=Handler(DblClickmsg)letoncontextmenumsg=Handler(ContextMenumsg)letonfocusmsg=Handler(Focusmsg)letoninputmsg=Handler(Inputmsg)letonchangemsg=Handler(Changemsg)letonchange_indexmsg=Handler(ChangeIndexmsg)letonchange_checkedmsg=Handler(ChangeCheckedmsg)letonblurmsg=Handler(Blurmsg)letonmousemovemsg=Handler(MouseMovemsg)letonkeydownmsg=Handler(KeyDownmsg)letonkeydown_cancelmsg=Handler(KeyDownCancelmsg)letoncustomeventmsg=Handler(CustomEventmsg)letstr_propkv=Property(k,Stringv)letint_propkv=Property(k,Intv)letbool_propkv=Property(k,Boolv)letfloat_propkv=Property(k,Floatv)letstylekv=Style(k,v)letattrkv=Attribute(k,v)letint_attrkv=Attribute(k,string_of_intv)letfloat_attrkv=Attribute(k,string_of_floatv)letscroll_to_show=bool_prop"scroll-to-show"trueletautofocus=bool_prop"autofocus"trueletautofocus_counterx=int_prop"autofocus"xletrelative_dropdownx=int_prop"relative-dropdown"xletclass_x=Property("className",Stringx)lettype_x=Property("type",Stringx)lettype_button=type_"button"letvaluex=Property("value",Stringx)letdisabledx=Property("disabled",Boolx)letadd_classxattrs=lethas_className=List.exists(functionProperty("className",_)->true|_->false)attrsinifhas_classNamethenList.map(function|Property("className",Strings)->Property("className",String(Printf.sprintf"%s %s"sx))|a->a)attrselseclass_x::attrstype+'msgvdom=|Textof{key:string;txt:string;}|Elementof{key:string;ns:string;tag:string;attributes:'msgattributelist;children:'msgvdomlist;}|Map:{key:string;f:('submsg->'msg);child:'submsgvdom;}->'msgvdom|Memo:{key:string;f:('a->'msgvdom);arg:'a;}->'msgvdom|Customof{key:string;elt:Custom.t;attributes:'msgattributelist;}lettext?(key="_txt")txt=Text{key;txt}type('msg,'res)elt_gen=?key:string->?a:'msgattributelist->'resletelt?(ns="")tag?key?(a=[])l=Element{key=(matchkeywithNone->tag|Somek->k);ns;tag;children=l;attributes=a;}letsvg_ns="http://www.w3.org/2000/svg"letsvg_elttag?key?al=elt~ns:svg_nstag?key?alletdiv?key?al=elt"div"?key?alletinput?key?al=elt"input"?key?allettxt_span?key?as=elt"span"?key?a[texts]letmap_attrf=function|Custom({attributes;_}asx)->Custom{xwithattributes=fattributes}|Element({attributes;_}asx)->Element{xwithattributes=fattributes}|x->xletmap?(key="_map")fchild=Map{key;f;child}letmemo?(key="_memo")farg=Memo{key;f;arg}letcustom?(key="_custom")?(a=[])elt=Custom{key;elt;attributes=a}letreturn?(c=[])model=model,Cmd.batchctype('model,'msg)app={init:('model*'msgCmd.t);update:('model->'msg->'model*'msgCmd.t);view:('model->'msgvdom);}letapp~init~update~view()={init;update;view}letsimple_app~init~update~view()=app~init:(returninit)~update:(funmodelmsg->return(updatemodelmsg))~view()typeevent={ev:'msg.('msgevent_handler->'msgoption)}letblur_event={ev=functionBlurmsg->Somemsg|_->None}letinput_events={ev=functionInputf->Some(fs)|_->None}letchecked_eventb={ev=functionChangeCheckedf->Some(fb)|_->None}letchange_events={ev=functionChangef->Some(fs)|_->None}letchange_index_eventi={ev=functionChangeIndexf->Some(fi)|_->None}letcustom_evente={ev=functionCustomEventf->fe|_->None}